@Override
 public MultipleDownloadTask<Object> gameJar(MinecraftDirectory mcdir, String version) {
   URI uri = getGameJar(version);
   if (uri == null) {
     return null;
   }
   return MultipleDownloadTask.simple(new FileDownloadTask(uri, mcdir.getVersionJar(version)));
 }
 @Override
 public MultipleDownloadTask<Object> asset(MinecraftDirectory mcdir, Asset asset) {
   URI uri = getAsset(asset);
   if (uri == null) {
     return null;
   }
   return MultipleDownloadTask.simple(
       new FileDownloadTask(uri, new File(mcdir.getAssetObjects(), asset.getPath())));
 }
  @Override
  public MultipleDownloadTask<RemoteVersionList> versionList() {
    URI uri = getVersionList();
    if (uri == null) {
      return null;
    }
    return MultipleDownloadTask.simple(
        new MemoryDownloadTask(uri)
            .andThen(
                new ResultProcessor<byte[], RemoteVersionList>() {

                  @Override
                  public RemoteVersionList process(byte[] arg) throws Exception {
                    return RemoteVersionList.fromJson(new JSONObject(new String(arg, "UTF-8")));
                  }
                }));
  }
  @Override
  public MultipleDownloadTask<Set<Asset>> assetsIndex(
      final MinecraftDirectory mcdir, final String version) {
    URI uri = getAssetIndex(version);
    if (uri == null) {
      return null;
    }
    return MultipleDownloadTask.simple(
        new FileDownloadTask(uri, mcdir.getAssetIndex(version))
            .andThen(
                new ResultProcessor<Object, Set<Asset>>() {

                  @Override
                  public Set<Asset> process(Object arg) throws IOException {
                    return Versions.resolveAssets(mcdir, version);
                  }
                }));
  }
 @Override
 public MultipleDownloadTask<Object> library(MinecraftDirectory mcdir, Library library) {
   URI uri = getLibrary(library);
   if (uri == null) {
     return null;
   }
   String path = uri.getPath();
   LibraryDownloadHandler handler = null;
   for (Entry<String, LibraryDownloadHandler> entry : libraryHandlers.entrySet()) {
     if (path.endsWith(entry.getKey())) {
       handler = entry.getValue();
       break;
     }
   }
   if (handler == null) {
     throw new IllegalArgumentException(
         "unable to resolve library download handler, path: " + path);
   }
   return MultipleDownloadTask.simple(
       handler.createDownloadTask(
           new File(mcdir.getLibraries(), library.getPath()), library, uri));
 }