private static boolean install(String patch, Path dest, UpdaterUI ui, boolean doBackup) {
    try {
      PatchFileCreator.PreparationResult preparationResult;
      File backupDir = null;
      PatchFileCreator.ApplicationResult applicationResult;

      try {
        File patchFile = Utils.getTempFile("patch");

        LOG.info("Extracting patch file...");
        ui.startProcess(UpdaterUI.message("extracting.patch.file"));
        ui.setProgressIndeterminate();
        try (ZipFile zipFile = new ZipFile(patch);
             InputStream in = Utils.getEntryInputStream(zipFile, PATCH_FILE_NAME);
             OutputStream out = new BufferedOutputStream(Files.newOutputStream(patchFile.toPath()))) {
          Utils.copyStream(in, out);
        }

        ui.checkCancelled();

        File destDir = dest.toFile();
        preparationResult = PatchFileCreator.prepareAndValidate(patchFile, destDir, ui);

        Map<String, ValidationResult.Option> resolutions = askForResolutions(preparationResult.validationResults, ui);

        if (doBackup) {
          backupDir = Utils.getTempFile("backup");
          if (!backupDir.mkdir()) throw new IOException("Cannot create a backup directory: " + backupDir);
        }

        applicationResult = PatchFileCreator.apply(preparationResult, resolutions, backupDir, ui);
      }
      catch (OperationCancelledException e) {
        LOG.log(Level.WARNING, "cancelled", e);
        return false;
      }
      catch (Throwable t) {
        LOG.log(Level.SEVERE, "prepare failed", t);
        String message = UpdaterUI.message("prepare.failed", t.getClass().getSimpleName(), t.getMessage()) + "\n\n" +
                         ui.bold(UpdaterUI.message("nothing.changed.retry")) + "\n\n" +
                         UpdaterUI.message("see.log", logPath);
        ui.showError(message);
        return false;
      }

      if (!applicationResult.applied) {
        List<PatchAction> appliedActions = applicationResult.appliedActions;
        Throwable error = applicationResult.error;

        if (error != null) {
          String message = UpdaterUI.message("apply.failed", error.getClass().getSimpleName(), error.getMessage()) + "\n\n";
          if (appliedActions.isEmpty()) {
            message += ui.bold(UpdaterUI.message("nothing.changed.retry"));
          }
          else if (backupDir == null) {
            message += ui.bold(UpdaterUI.message("corrupted.reinstall"));
          }
          else {
            message += ui.bold(UpdaterUI.message("corrupted.reverting"));
          }
          message += "\n\n" + UpdaterUI.message("see.log", logPath);
          ui.showError(message);
        }

        if (!appliedActions.isEmpty() && backupDir != null) {
          try {
            PatchFileCreator.revert(preparationResult, appliedActions, backupDir, ui);
          }
          catch (Throwable t) {
            LOG.log(Level.SEVERE, "revert failed", t);
            String message = UpdaterUI.message("revert.failed", t.getClass().getSimpleName(), t.getMessage()) + "\n\n" +
                             ui.bold(UpdaterUI.message("corrupted.reinstall")) + "\n\n" +
                             UpdaterUI.message("see.log", logPath);
            ui.showError(message);
          }
        }
      }

      return applicationResult.applied;
    }
    finally {
      try {
        cleanup(ui);
        refreshApplicationIcon(dest.toString());
      }
      catch (Throwable t) {
        LOG.log(Level.WARNING, "cleanup failed", t);
      }
    }
  }
private static boolean install(String patch, Path dest, UpdaterUI ui, boolean doBackup)