public ArtifactData getCandidateAsync(String arg) throws Exception {
    reporter.trace("coordinate %s", arg);
    if (isUrl(arg))
      try {
        ArtifactData data = putAsync(new URI(arg));
        data.local = true;
        return data;
      } catch (Exception e) {
        reporter.trace("hmm, not a valid url %s, will try the server", arg);
      }

    Coordinate c = new Coordinate(arg);

    if (c.isSha()) {
      ArtifactData r = get(c.getSha());
      if (r != null) return r;
    }

    Revision revision = library.getRevisionByCoordinate(c);
    if (revision == null) return null;

    reporter.trace("revision %s", Hex.toHexString(revision._id));

    ArtifactData ad = get(revision._id);
    if (ad != null) {
      reporter.trace("found in cache");
      return ad;
    }

    URI url = revision.urls.iterator().next();
    ArtifactData artifactData = putAsync(url);
    artifactData.coordinate = c;
    return artifactData;
  }
 /**
  * Returns a String representation of {@code position}.
  *
  * @param position the {@link Coordinate} instance
  * @return a String representation of {@code position}
  */
 @SuppressWarnings("unused")
 private static String toString(final Coordinate position) {
   return "Coordinate{"
       + "x="
       + position.getX()
       + ", y="
       + position.getY()
       + ", z="
       + position.getZ()
       + ", phi="
       + position.getPhi()
       + ", theta="
       + position.getTheta()
       + '}';
 }