public static boolean doLauncherUpdate(Stack<String> updateQueue, JSONObject versionsConfig) {
        
        Logger.info("Updater.doLauncherUpdate", "Starting update...");
        
        //Show progress
        GlobalDialogs.showProgressDialog();
        GlobalDialogs.setProgressCaption("Cleaning...");
        GlobalDialogs.setProgressIndeterminate(true);
        
        //Clean patch directory
        Logger.info("Updater.doLauncherUpdate", "Cleaning patch directory...");
        try {
            if (new File("./update/launcherpatch").isDirectory()) {
                FileUtils.deleteDirectory(new File("./update/launcherpatch"));
            }
        } catch (IOException ex) {
            Logger.error("Updater.doLauncherUpdate", "Failed to clean the patch directory!", false, ex);
            GlobalDialogs.hideProgressDialog();
            GlobalDialogs.showNotification("Failed to clean the patch directory!");
            return false;
        }
        
        //Download and extract patches
        while (!updateQueue.empty()) {
            //Load update from JSON
            String updateName = updateQueue.pop();
            JSONObject update = getVersionByName(updateName, "moddle", versionsConfig);
            
            //Update status
            GlobalDialogs.setProgressCaption("Getting patch '" + updateName + "'...");

            //Download version patch
            Logger.info("Updater.doLauncherUpdate", "Downloading patch '" + updateName + "'...");
            try {
                FileUtils.copyURLToFile(new URL(update.get("patch").toString()), new File("./update/moddle-" + updateName + "-patch.zip"));
            } catch (IOException ex) {
                Logger.error("Updater.doLauncherUpdate", "Failed to download patch!", false, ex);
                GlobalDialogs.hideProgressDialog();
                GlobalDialogs.showNotification("Failed to download patch '" + updateName + "'!");
                return false;
            }

            //Extract version patch
            Logger.info("Updater.doLauncherUpdate", "Extracting patch '" + updateName + "'...");
            try {
                Util.decompressZipfile("./update/moddle-" + updateName + "-patch.zip", "./update/launcherpatch");
            } catch (ZipException ex) {
                Logger.error("Updater.doLauncherUpdate", "Failed to extract patch!", false, ex);
                GlobalDialogs.hideProgressDialog();
                GlobalDialogs.showNotification("Failed to extract patch '" + updateName + "'!");
                return false;
            }
        }
        
        //Update status
        GlobalDialogs.setProgressCaption("Restarting...");
        
        //Start MUpdate
        ProcessBuilder updater = new ProcessBuilder(new String[] { "javaw.exe", "-jar", "\"" + Util.getFullPath("./update/MUpdate.jar") + "\"", "--version=" + versionsConfig.get("latestmoddle").toString() });
        updater.directory(new File("./update"));
        try {
            updater.start();
        } catch (Exception ex) {
            Logger.error("Updater.doLauncherUpdate", "Failed to start MUpdate!", false, ex);
            GlobalDialogs.hideProgressDialog();
            GlobalDialogs.showNotification("Could not start MUpdate!");
            return false;
        }
        
        //Exit Moddle
        GlobalDialogs.hideProgressDialog();
        System.exit(0);
        
        return true;
    }