private static void _main(String[] args) {
    String jarFile = getArgument(args, "jar");
    if (jarFile == null) {
      jarFile = resolveJarFile();
    }

    LOG.info("args: " + Arrays.toString(args));
    LOG.info(".jar: " + jarFile);

    if (args.length >= 6 && "create".equals(args[0])) {
      String oldVersionDesc = args[1];
      String newVersionDesc = args[2];
      String oldFolder = args[3];
      String newFolder = args[4];
      String patchFile = args[5];

      checkCaseSensitivity(newFolder);

      LOG.info("case-sensitive: " + ourCaseSensitiveFs);

      boolean strict = hasArgument(args, "strict");

      String root = getArgument(args, "root");
      if (root == null) {
        root = "";
      }
      else if (!root.endsWith("/")) {
        root += "/";
      }

      List<String> ignoredFiles = extractArguments(args, "ignored");
      List<String> strictFiles = extractArguments(args, "strictfiles");
      List<String> criticalFiles = extractArguments(args, "critical");
      List<String> optionalFiles = extractArguments(args, "optional");
      List<String> deleteFiles = extractArguments(args, "delete");

      String timeoutStr = getArgument(args, "timeout");
      int timeout = timeoutStr != null ? Integer.parseInt(timeoutStr) : 0;

      String cacheDir = getArgument(args, "cache-dir");

      PatchSpec spec = new PatchSpec()
        .setOldVersionDescription(oldVersionDesc)
        .setNewVersionDescription(newVersionDesc)
        .setRoot(root)
        .setOldFolder(oldFolder)
        .setNewFolder(newFolder)
        .setPatchFile(patchFile)
        .setJarFile(jarFile)
        .setStrict(strict)
        .setIgnoredFiles(ignoredFiles)
        .setCriticalFiles(criticalFiles)
        .setStrictFiles(strictFiles)
        .setOptionalFiles(optionalFiles)
        .setDeleteFiles(deleteFiles)
        .setTimeout(timeout);

      boolean success = create(spec, cacheDir != null ? Path.of(cacheDir) : null);
      System.exit(success ? 0 : 1);
    }
    else if (args.length >= 2 && ("install".equals(args[0]) || "apply".equals(args[0])) ||
             args.length >= 3 && ("batch-install".equals(args[0]))) {
      LOG.info("JRE: " + System.getProperty("java.runtime.version", "unknown") + " @ " + System.getProperty("java.home"));
      LOG.info("user.language=" + System.getProperty("user.language") + " user.country=" + System.getProperty("user.country"));

      String destPath = args[1];

      Path destDirectory = Path.of(destPath);
      try {
        destDirectory = destDirectory.toRealPath();
      }
      catch (InvalidPathException | IOException e) {
        LOG.log(Level.SEVERE, destPath, e);
      }

      checkCaseSensitivity(destDirectory.toString());

      LOG.info("destination: " + destPath + " (" + destDirectory + "), case-sensitive: " + ourCaseSensitiveFs);

      var ui = "apply".equals(args[0]) ? new ConsoleUpdaterUI(hasArgument(args, "force-replace")) : SwingUpdaterUI.createUI();

      boolean backup = !hasArgument(args, "no-backup");
      boolean success;
      if (!Files.isDirectory(destDirectory, LinkOption.NOFOLLOW_LINKS)) {
        ui.showError(UpdaterUI.message("invalid.target.directory", destPath));
        success = false;
      }
      else if (!"batch-install".equals(args[0])) {
        success = install(jarFile, destDirectory, ui, backup);
      }
      else {
        String[] patches = args[2].split(File.pathSeparator);
        success = install(patches, destDirectory, ui, backup);
      }
      System.exit(success ? 0 : 1);
    }
    else {
      printUsage();
      System.exit(1);
    }
  }
private static void _main(String[] args)