/*
   * Estimates the "weight" (a unitless value) of the given item.  This is
   * counted as 1 per content and metadata file in the item, plus 100 per
   * gigabyte of streamed data (so that files of 1GB or more cause the batch
   * to end).
   */
  private final int weight(final BulkImportItem<BulkImportItemVersion> item) {
    int result = 0;

    for (final BulkImportItemVersion version : item.getVersions()) {
      result++;

      if (version.hasContent() && !version.contentIsInPlace()) {
        result += (int) ((float) item.sizeInBytes() / ONE_GIGABYTE * 100);
      }
    }

    return (result);
  }
  /**
   * @see
   *     org.alfresco.extension.bulkimport.BulkImportCallback#submit(org.alfresco.extension.bulkimport.source.BulkImportItem)
   */
  @Override
  @SuppressWarnings({"rawtypes", "unchecked"})
  public synchronized void submit(final BulkImportItem item) throws InterruptedException {
    // PRECONDITIONS
    if (item == null) {
      throw new IllegalArgumentException(
          "Import source '"
              + source.getName()
              + "' has logic errors - a null import item was submitted.");
    }

    if (item.getVersions() == null || item.getVersions().size() <= 0) {
      throw new IllegalArgumentException(
          "Import source '"
              + source.getName()
              + "' has logic errors - an empty import item was submitted.");
    }

    // Body
    if (importStatus.isStopping() || Thread.currentThread().isInterrupted())
      throw new InterruptedException(
          Thread.currentThread().getName() + " was interrupted. Terminating early.");

    // If the weight of the new item would blow out the current batch, submit the batch as-is (i.e.
    // *before* adding the newly submitted item).
    // This ensures that heavy items start a new batch (and possibly end up in a batch by
    // themselves).
    int weight = weight(item);

    if (weightOfCurrentBatch + weight > batchWeight) {
      submitCurrentBatch();
    }

    // Create a new batch, if necessary
    if (currentBatch == null) {
      currentBatchNumber++;
      currentBatch = new ArrayList<>(batchWeight);
      weightOfCurrentBatch = 0;
    }

    // Finally, add the item to the current batch
    currentBatch.add(item);
    weightOfCurrentBatch += weight;
  }