private void copyHelper(
      AuthData exportAuthData,
      AuthData importAuthData,
      UUID jobId,
      Optional<ExportInformation> exportInfo)
      throws CopyException {

    String jobIdPrefix = "Job " + jobId + ": ";
    final int copyIteration = COPY_ITERATION_COUNTER.incrementAndGet();

    // NOTE: order is important below, do the import of all the items, then do continuation
    // then do sub resources, this ensures all parents are populated before children get
    // processed.

    ExportResult<?> exportResult =
        copyIteration(
            jobId, exportAuthData, importAuthData, exportInfo, jobIdPrefix, copyIteration);

    // Import and Export were successful, determine what to do next
    ContinuationData continuationData = exportResult.getContinuationData();

    if (null != continuationData) {
      // Process the next page of items for the resource
      if (null != continuationData.getPaginationData()) {
        monitor.debug(
            () ->
                jobIdPrefix
                    + "Starting off a new copy iteration with pagination info, copy iteration: "
                    + copyIteration);
        copyHelper(
            exportAuthData,
            importAuthData,
            jobId,
            Optional.of(
                new ExportInformation(
                    continuationData.getPaginationData(),
                    exportInfo.isPresent() ? exportInfo.get().getContainerResource() : null)));
      }

      // Start processing sub-resources
      if (continuationData.getContainerResources() != null
          && !continuationData.getContainerResources().isEmpty()) {
        for (ContainerResource resource : continuationData.getContainerResources()) {
          monitor.debug(
              () ->
                  jobIdPrefix
                      + "Starting off a new copy iteration with a new container resource, copy"
                      + " iteration: "
                      + copyIteration);
          copyHelper(
              exportAuthData,
              importAuthData,
              jobId,
              Optional.of(new ExportInformation(null, resource)));
        }
      }
    }
  }
Transfers data from the given {@code exporter} optionally starting at the point specified in
the provided {@code exportInfo}. Imports the data using the provided {@code importer}. If there
is more data to required to be exported, recursively copies using the specific {@link
ExportInformation} to continue the process.

@param exportAuthData The auth data for the export
@param importAuthData The auth data for the import
@param exportInfo Any pagination or resource information to use for subsequent calls.
portability-transfer/src/main/java/org/datatransferproject/transfer/copier/PortabilityInMemoryDataCopier.java