@Override
 public void put(
     Collection<? extends ArtifactUpload> artifactUploads,
     Collection<? extends MetadataUpload> metadataUploads) {
   if (artifactUploads != null) {
     for (ArtifactUpload a : artifactUploads) {
       a.setException(new ArtifactNotFoundException(a.getArtifact(), repository));
     }
   }
   if (metadataUploads != null) {
     for (MetadataUpload m : metadataUploads) {
       m.setException(new MetadataNotFoundException(m.getMetadata(), repository));
     }
   }
 }
  /**
   * Use the async http client library to upload artifacts and metadata.
   *
   * @param artifactUploads The artifact uploads to perform, may be {@code null} or empty.
   * @param metadataUploads The metadata uploads to perform, may be {@code null} or empty.
   */
  public void put(
      Collection<? extends ArtifactUpload> artifactUploads,
      Collection<? extends MetadataUpload> metadataUploads) {
    if (closed.get()) {
      throw new IllegalStateException("connector closed");
    }

    artifactUploads = safe(artifactUploads);
    metadataUploads = safe(metadataUploads);

    CountDownLatch latch = new CountDownLatch(artifactUploads.size() + metadataUploads.size());

    Collection<PutTask<?>> tasks = new ArrayList<PutTask<?>>();

    for (ArtifactUpload upload : artifactUploads) {
      String path = layout.getPath(upload.getArtifact()).getPath();

      PutTask<?> task =
          new PutTask<ArtifactTransfer>(path, upload.getFile(), latch, upload, ARTIFACT);
      tasks.add(task);
      task.run();
    }

    for (MetadataUpload upload : metadataUploads) {
      String path = layout.getPath(upload.getMetadata()).getPath();

      PutTask<?> task =
          new PutTask<MetadataTransfer>(path, upload.getFile(), latch, upload, METADATA);
      tasks.add(task);
      task.run();
    }

    try {
      latch.await();

      for (PutTask<?> task : tasks) {
        task.flush();
      }
    } catch (InterruptedException e) {
      for (PutTask<?> task : tasks) {
        task.flush(e);
      }
    }
  }