docs: public synchronized CopyPartRequest getNextCopyPartRequest() {
          final long partSize = Math.min(optimalPartSize, remainingBytes);
  
          CopyPartRequest req = new CopyPartRequest()
              .withSourceBucketName(origReq.getSourceBucketName())
              .withSourceKey(origReq.getSourceKey())
              .withUploadId(uploadId)
              .withPartNumber(partNumber++)
              .withDestinationBucketName(origReq.getDestinationBucketName())
              .withDestinationKey(origReq.getDestinationKey())
              .withSourceVersionId(origReq.getSourceVersionId())
              .withFirstByte(Long.valueOf(offset))
              .withLastByte(Long.valueOf(offset + partSize - 1))
              .withSourceSSECustomerKey(origReq.getSourceSSECustomerKey())
              .withDestinationSSECustomerKey(origReq.getDestinationSSECustomerKey())
              .withRequesterPays(origReq.isRequesterPays())
              // other meta data
              .withMatchingETagConstraints(origReq.getMatchingETagConstraints())
              .withModifiedSinceConstraint(origReq.getModifiedSinceConstraint())
              .withNonmatchingETagConstraints(origReq.getNonmatchingETagConstraints())
              .withSourceVersionId(origReq.getSourceVersionId())
              .withUnmodifiedSinceConstraint(origReq.getUnmodifiedSinceConstraint())
              // general meta data
              .withGeneralProgressListener(origReq.getGeneralProgressListener())
              .withRequestMetricCollector(origReq.getRequestMetricCollector())
              ;
          offset += partSize;
          remainingBytes -= partSize;
          return req;
      }