protected void installAssets(@NonNull Installer installer,
@NonNull VersionManifest versionManifest,
@NonNull URL indexUrl,
@NonNull List<URL> sources) throws IOException, InterruptedException {
AssetsRoot assetsRoot = launcher.getAssets();
AssetsIndex index = HttpRequest
.get(indexUrl)
.execute()
.expectResponseCode(200)
.returnContent()
.saveContent(assetsRoot.getIndexPath(versionManifest))
.asJson(AssetsIndex.class);
// Keep track of duplicates
Set<String> downloading = new HashSet<String>();
for (Map.Entry<String, Asset> entry : index.getObjects().entrySet()) {
checkInterrupted();
String hash = entry.getValue().getHash();
String path = String.format("%s/%s", hash.subSequence(0, 2), hash);
File targetFile = assetsRoot.getObjectPath(entry.getValue());
if (!targetFile.exists() && !downloading.contains(path)) {
List<URL> urls = new ArrayList<URL>();
for (URL sourceUrl : sources) {
try {