public <T extends DownloadableFile> long uploadItemsViaBatching(
      Collection<T> items, ItemBatchUploader<T> importer) throws Exception {
    long bytes = 0L;
    if (items == null || items.size() <= 0) {
      return bytes;
    }
    Map<String, List<T>> itemsByAlbumId =
        items.stream()
            .filter(
                item -> !executor.isKeyCached(item.getIdempotentId()) && item.getFolderId() != null)
            .collect(Collectors.groupingBy(DownloadableFile::getFolderId));
    // Null album-id items get sent here into the empty string key
    itemsByAlbumId.put(
        format(ALBUMLESS_IDENTIFIER, jobId),
        items.stream()
            .filter(
                item -> !executor.isKeyCached(item.getIdempotentId()) && item.getFolderId() == null)
            .collect(Collectors.toList()));

    for (Entry<String, List<T>> albumEntry : itemsByAlbumId.entrySet()) {
      String originalAlbumId = albumEntry.getKey();
      String googleAlbumId;
      if (Strings.isNullOrEmpty(originalAlbumId) || originalAlbumId.equals(format(ALBUMLESS_IDENTIFIER, jobId))) {
        // This is ok, since NewMediaItemUpload will ignore all null values and it's possible to
        // upload a NewMediaItem without a corresponding album id.
        googleAlbumId = null;
      } else {
        // Note this will throw if creating the album failed, which is what we want
        // because that will also mark this photo as being failed.
        googleAlbumId = executor.getCachedValue(originalAlbumId);
      }

      UnmodifiableIterator<List<T>> batches =
          Iterators.partition(albumEntry.getValue().iterator(), BATCH_UPLOAD_SIZE);

      while (batches.hasNext()) {
        long batchBytes =
            importer.uploadToAlbum(jobId, authData, batches.next(), executor, googleAlbumId);
        bytes += batchBytes;
      }
    }
    return bytes;
  }
Imports all `items` by fanning out to `batchImporter` upload calls as specified by the.

<p>Returns the number of uploaded bytes, as summed across all `items` that were uploaded.
extensions/data-transfer/portability-data-transfer-google/src/main/java/org/datatransferproject/datatransfer/google/common/gphotos/GPhotosUpload.java