// Path: bin/src/io/github/alechenninger/monarch/apply/ApplyChangesInput.java
// public interface ApplyChangesInput {
//   Optional<String> getHierarchyPathOrYaml();
// 
//   Optional<String> getChangesPathOrYaml();
// 
//   Optional<SourceSpec> getTarget();
// 
//   Optional<String> getDataDir();
// 
//   List<String> getConfigPaths();
// 
//   Optional<String> getOutputDir();
// 
//   List<String> getMergeKeys();
// 
//   boolean isHelpRequested();
// 
//   String getHelpMessage();
// 
//   Optional<YamlConfiguration.Isolate> getYamlIsolate();
// 
// }
// 
// Path: bin/src/io/github/alechenninger/monarch/set/UpdateSetInput.java
// public interface UpdateSetInput {
//   /**
//    * Path of changes to read from and update (or create, if the path does not exist).
//    */
//   Optional<String> getChangesPath();
// 
//   /**
//    * Source for the change we wish to modify or create.
//    */
//   Optional<SourceSpec> getSource();
// 
//   /**
//    * A list of key value pairs to add or replace in the set block of the source's change.
//    *
//    * <p>The list may contain paths to yaml files or inline yaml heterogeneously.
//    */
//   List<String> getPutPathsOrYaml();
// 
//   /**
//    * A list of keys to remove from the set block of the source's change.
//    */
//   List<String> getRemovals();
// 
//   Optional<String> getHierarchyPathOrYaml();
// 
//   List<String> getConfigPaths();
// 
//   boolean isHelpRequested();
// 
//   String getHelpMessage();
// }
// 
// Path: bin/src/io/github/alechenninger/monarch/yaml/YamlConfiguration.java
// public interface YamlConfiguration {
//   YamlConfiguration DEFAULT = new Default();
// 
//   default int indent() {
//     return 2;
//   }
// 
//   default Isolate updateIsolation() {
//     return Isolate.ALWAYS;
//   }
// 
//   enum Isolate {
//     ALWAYS,
//     // TODO: Support WHEN_POSSIBLE
//     // This involves modifying unmanaged portion while maintaining formatting and whitespace.
//     // Not trivial to do.
//     //WHEN_POSSIBLE,
//     NEVER;
//   }
// 
//   /** Extendable for reusable toString */
//   class Default implements YamlConfiguration {
//     @Override
//     public String toString() {
//       return "YamlConfiguration{" +
//           "indent=" + indent() +
//           ", updateIsolation=" + updateIsolation() +
//           '}';
//     }
//   }
// }


import io.github.alechenninger.monarch.apply.ApplyChangesInput;
import io.github.alechenninger.monarch.set.UpdateSetInput;
import io.github.alechenninger.monarch.yaml.YamlConfiguration;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.impl.action.StoreTrueArgumentAction;
import net.sourceforge.argparse4j.inf.Argument;
import net.sourceforge.argparse4j.inf.ArgumentAction;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import net.sourceforge.argparse4j.internal.UnrecognizedArgumentException;
import net.sourceforge.argparse4j.internal.UnrecognizedCommandException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import java.util.stream.Collectors;
    parser.addArgument("-?", "--help")
        .dest("help")
        .action(new AbortParsingAction(Arguments.storeTrue()))
        .help("Show this message and exit.");

    parser.addArgument("-v", "--version")
        .dest("show_version")
        .action(new AbortParsingAction(Arguments.storeTrue()))
        .help("Show the running version of monarch and exit.");

    MutuallyExclusiveGroup logGroup = parser.addMutuallyExclusiveGroup("logging flags")
        .description("Control log levels. Without either flag, some logs are written. " +
            "Errors and warnings are output to stderr.");

    logGroup.addArgument("--verbose")
        .action(new StoreTrueArgumentAction())
        .setDefault(false)
        .dest("verbose")
        .help("Log everything. Useful to understand what your changeset is doing.");

    logGroup.addArgument("--quiet")
        .action(new StoreTrueArgumentAction())
        .setDefault(false)
        .dest("quiet")
        .help("Log nothing.");

    Subparsers subparsers = parser.addSubparsers().dest(SUBPARSER_DEST)
        .title("commands")
        .help("Pass --help to a command for more information.");

// Path: bin/src/io/github/alechenninger/monarch/apply/ApplyChangesInput.java
// public interface ApplyChangesInput {
//   Optional<String> getHierarchyPathOrYaml();
// 
//   Optional<String> getChangesPathOrYaml();
// 
//   Optional<SourceSpec> getTarget();
// 
//   Optional<String> getDataDir();
// 
//   List<String> getConfigPaths();
// 
//   Optional<String> getOutputDir();
// 
//   List<String> getMergeKeys();
// 
//   boolean isHelpRequested();
// 
//   String getHelpMessage();
// 
//   Optional<YamlConfiguration.Isolate> getYamlIsolate();
// 
// }
// 
// Path: bin/src/io/github/alechenninger/monarch/set/UpdateSetInput.java
// public interface UpdateSetInput {
//   /**
//    * Path of changes to read from and update (or create, if the path does not exist).
//    */
//   Optional<String> getChangesPath();
// 
//   /**
//    * Source for the change we wish to modify or create.
//    */
//   Optional<SourceSpec> getSource();
// 
//   /**
//    * A list of key value pairs to add or replace in the set block of the source's change.
//    *
//    * <p>The list may contain paths to yaml files or inline yaml heterogeneously.
//    */
//   List<String> getPutPathsOrYaml();
// 
//   /**
//    * A list of keys to remove from the set block of the source's change.
//    */
//   List<String> getRemovals();
// 
//   Optional<String> getHierarchyPathOrYaml();
// 
//   List<String> getConfigPaths();
// 
//   boolean isHelpRequested();
// 
//   String getHelpMessage();
// }
// 
// Path: bin/src/io/github/alechenninger/monarch/yaml/YamlConfiguration.java
// public interface YamlConfiguration {
//   YamlConfiguration DEFAULT = new Default();
// 
//   default int indent() {
//     return 2;
//   }
// 
//   default Isolate updateIsolation() {
//     return Isolate.ALWAYS;
//   }
// 
//   enum Isolate {
//     ALWAYS,
//     // TODO: Support WHEN_POSSIBLE
//     // This involves modifying unmanaged portion while maintaining formatting and whitespace.
//     // Not trivial to do.
//     //WHEN_POSSIBLE,
//     NEVER;
//   }
// 
//   /** Extendable for reusable toString */
//   class Default implements YamlConfiguration {
//     @Override
//     public String toString() {
//       return "YamlConfiguration{" +
//           "indent=" + indent() +
//           ", updateIsolation=" + updateIsolation() +
//           '}';
//     }
//   }
// }


// Path: bin/src/io/github/alechenninger/monarch/ArgParseMonarchArgParser.java
import io.github.alechenninger.monarch.apply.ApplyChangesInput;
import io.github.alechenninger.monarch.set.UpdateSetInput;
import io.github.alechenninger.monarch.yaml.YamlConfiguration;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.impl.action.StoreTrueArgumentAction;
import net.sourceforge.argparse4j.inf.Argument;
import net.sourceforge.argparse4j.inf.ArgumentAction;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import net.sourceforge.argparse4j.internal.UnrecognizedArgumentException;
import net.sourceforge.argparse4j.internal.UnrecognizedCommandException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import java.util.stream.Collectors;

    parser.addArgument("-?", "--help")
        .dest("help")
        .action(new AbortParsingAction(Arguments.storeTrue()))
        .help("Show this message and exit.");

    parser.addArgument("-v", "--version")
        .dest("show_version")
        .action(new AbortParsingAction(Arguments.storeTrue()))
        .help("Show the running version of monarch and exit.");

    MutuallyExclusiveGroup logGroup = parser.addMutuallyExclusiveGroup("logging flags")
        .description("Control log levels. Without either flag, some logs are written. " +
            "Errors and warnings are output to stderr.");

    logGroup.addArgument("--verbose")
        .action(new StoreTrueArgumentAction())
        .setDefault(false)
        .dest("verbose")
        .help("Log everything. Useful to understand what your changeset is doing.");

    logGroup.addArgument("--quiet")
        .action(new StoreTrueArgumentAction())
        .setDefault(false)
        .dest("quiet")
        .help("Log nothing.");

    Subparsers subparsers = parser.addSubparsers().dest(SUBPARSER_DEST)
        .title("commands")
        .help("Pass --help to a command for more information.");

    InputFactory<ApplyChangesInput> applyChangesFactory = applySpec.addToSubparsers(subparsers);