public boolean downloadModPackage(String name, String filename, File downloadedFile) {
   try {
     // Install from cache if md5 matches otherwise download and insert
     // to cache
     File modCache = new File(cacheDir, filename);
     String md5Name = "mods\\" + name + "\\" + filename;
     if (modCache.exists() && MD5Utils.checksumCachePath(filename, md5Name)) {
       stateChanged("Copying " + filename + " from cache", 0);
       copy(modCache, downloadedFile);
       stateChanged("Copied " + filename + " from cache", 100);
       return true;
     } else {
       String mirrorURL = "mods/" + name + "/" + filename;
       String fallbackURL = fallbackModsURL + name + "/" + filename;
       String url = MirrorUtils.getMirrorUrl(mirrorURL, fallbackURL, this);
       String fileMD5 = MD5Utils.getMD5FromList(mirrorURL);
       Download download =
           DownloadUtils.downloadFile(url, downloadedFile.getPath(), filename, fileMD5, this);
       return download.isSuccess();
     }
   } catch (MalformedURLException e) {
     Util.log(
         "Cannot download the mod '%s'. Does the exact filename exist on the mirror?",
         "mods/" + name + "/" + filename);
   } catch (IOException e) {
     e.printStackTrace();
   }
   return false;
 }
  public void updateModPackMods() {
    try {

      Map<String, Object> modLibrary =
          (Map<String, Object>) ModLibraryYML.getModLibraryYML().getProperty("mods");
      Map<String, Object> currentModList = ModpackBuild.getSpoutcraftBuild().getMods();

      // Remove Mods no longer in previous version
      removeOldMods(currentModList.keySet());

      for (Map.Entry<String, Object> modEntry2 : currentModList.entrySet()) {
        String modName = modEntry2.getKey();

        if (!modLibrary.containsKey(modName)) {
          throw new IOException(String.format("Mod '%s' is missing from the mod library", modName));
        }

        Map<String, Object> modProperties = (Map<String, Object>) modLibrary.get(modName);
        Map<String, Object> modVersions = (Map<String, Object>) modProperties.get("versions");

        String version = modEntry2.getValue().toString();

        if (!modVersions.containsKey(version)) {
          throw new IOException(
              String.format(
                  "Mod '%s' version '%s' is missing from the mod library", modName, version));
        }

        String installType =
            modProperties.containsKey("installtype")
                ? (String) modProperties.get("installtype")
                : "zip";
        String fullFilename = modName + "-" + version + "." + installType;
        Boolean isOptional =
            modProperties.containsKey("optional") ? (Boolean) modProperties.get("optional") : false;

        String installedModVersion = InstalledModsYML.getInstalledModVersion(modName);

        // If installed mods md5 hash is the same as server's version
        // then go to next mod.
        if (installedModVersion != null && installedModVersion.equals(version)) {
          String md5ModPath = String.format("mods/%s/%s", modName, fullFilename);
          if (MD5Utils.checksumCachePath(fullFilename, md5ModPath)) {
            continue;
          }
        }

        File modFile = new File(tempDir, fullFilename);

        // If have the mod file then update
        if (downloadModPackage(modName, fullFilename, modFile)) {
          updateMod(modFile, modName, version);
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public boolean isModpackUpdateAvailable() throws IOException {

    Map<String, Object> modLibrary =
        (Map<String, Object>) ModLibraryYML.getModLibraryYML().getProperty("mods");
    Map<String, Object> currentModList = ModpackBuild.getSpoutcraftBuild().getMods();

    for (Map.Entry<String, Object> modEntry2 : currentModList.entrySet()) {
      String modName = modEntry2.getKey();

      if (!modLibrary.containsKey(modName)) {
        throw new IOException("Mod is missing from the mod library");
      }

      Map<String, Object> modProperties = (Map<String, Object>) modLibrary.get(modName);
      Map<String, Object> modVersions = (Map<String, Object>) modProperties.get("versions");

      String version = modEntry2.getValue().toString();

      if (!modVersions.containsKey(version)) {
        throw new IOException("Mod version is missing from the mod library");
      }

      String installType = modProperties.get("installtype").toString();
      String fullFilename = modName + "-" + version + "." + installType;

      String md5Name = "mods\\" + modName + "\\" + fullFilename;
      if (!MD5Utils.checksumCachePath(fullFilename, md5Name)) {
        return true;
      }
      int a = 1;
      String installedModVersion = InstalledModsYML.getInstalledModVersion(modName);
      if (installedModVersion == null || !installedModVersion.equals(version)) {
        return true;
      }
    }

    return false;
  }
  private static Map<String, String> getModPackResources(String name, File path, boolean doCheck) {
    Map<String, String> fileMap = new HashMap<String, String>();

    for (String resource : RESOURCES) {
      String relativeFilePath = name + "/resources/" + resource;

      if (doCheck && MD5Utils.checksumPath(relativeFilePath)) {
        continue;
      }

      File dir = new File(path, RESOURCES_PATH);
      dir.mkdirs();
      File file = new File(dir, resource);
      String filePath = file.getAbsolutePath();

      String fileURL = MirrorUtils.getMirrorUrl(relativeFilePath, null);
      if (fileURL == null) {
        continue;
      }
      fileMap.put(fileURL, filePath);
    }

    return fileMap;
  }