private void removePreviousModVersion(String modName, String installedVersion) {
    try {
      // Mod has been previously installed uninstall previous version
      File previousModZip = new File(cacheDir, modName + "-" + installedVersion + ".zip");
      ZipFile zf = new ZipFile(previousModZip);
      Enumeration<? extends ZipEntry> entries = zf.entries();
      // Go through zipfile of previous version and delete all file from
      // Modpack that exist in the zip
      while (entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        if (entry.isDirectory()) {
          continue;
        }
        File file = new File(GameUpdater.modpackDir, entry.getName());
        Util.log("Deleting '%s'", entry.getName());
        if (file.exists()) {
          // File from mod exists.. delete it
          file.delete();
        }
      }

      InstalledModsYML.removeMod(modName);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public void updateMod(File modFile, String modName, String modVersion) {
    // Check if previous version of mod is installed
    String installedVersion = InstalledModsYML.getInstalledModVersion(modName);

    if (installedVersion != null) {
      removePreviousModVersion(modName, installedVersion);
    }

    stateChanged("Extracting Files ...", 0);
    // Extract Natives
    extractNatives2(GameUpdater.modpackDir, modFile);

    InstalledModsYML.setInstalledModVersion(modName, modVersion);

    modFile.delete();
  }
  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();
    }
  }
  private void removeOldMods(Set<String> modsToInstall) {
    Map<String, String> installedMods = InstalledModsYML.getInstalledMods();

    if (installedMods == null || modsToInstall == null || modsToInstall.size() <= 0) {
      return;
    }

    Set<String> modsToRemove = installedMods.keySet();
    modsToRemove.removeAll(modsToInstall);

    String[] array = new String[modsToRemove.size()];
    modsToRemove.toArray(array);
    for (String modName : array) {
      removePreviousModVersion(modName, installedMods.get(modName));
    }
  }
  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;
  }