/**
   * Parses the given command-line.
   *
   * @param commandLine The command-line.
   * @return The parsed command line.
   * @throws org.gradle.CommandLineArgumentException On parse failure.
   */
  public ParsedCommandLine parse(Iterable<String> commandLine) {
    ParsedCommandLine parsedCommandLine =
        new ParsedCommandLine(new HashSet<CommandLineOption>(optionsByString.values()));
    ParserState parseState = new BeforeFirstSubCommand(parsedCommandLine);
    for (String arg : commandLine) {
      if (parseState.maybeStartOption(arg)) {
        if (arg.equals("--")) {
          parseState = new AfterOptions(parsedCommandLine);
        } else if (arg.matches("--[^=]+")) {
          OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(2));
          parseState = parsedOption.onStartNextArg();
        } else if (arg.matches("--[^=]+=.*")) {
          int endArg = arg.indexOf('=');
          OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(2, endArg));
          parseState = parsedOption.onArgument(arg.substring(endArg + 1));
        } else if (arg.matches("-[^=]=.*")) {
          OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(1, 2));
          parseState = parsedOption.onArgument(arg.substring(3));
        } else {
          assert arg.matches("-[^-].*");
          String option = arg.substring(1);
          if (optionsByString.containsKey(option)) {
            OptionParserState parsedOption = parseState.onStartOption(arg, option);
            parseState = parsedOption.onStartNextArg();
          } else {
            String option1 = arg.substring(1, 2);
            OptionParserState parsedOption = parseState.onStartOption("-" + option1, option1);
            if (parsedOption.getHasArgument()) {
              parseState = parsedOption.onArgument(arg.substring(2));
            } else {
              parseState = parsedOption.onComplete();
              for (int i = 2; i < arg.length(); i++) {
                String optionStr = arg.substring(i, i + 1);
                parsedOption = parseState.onStartOption("-" + optionStr, optionStr);
                parseState = parsedOption.onComplete();
              }
            }
          }
        }
      } else {
        parseState = parseState.onNonOption(arg);
      }
    }

    parseState.onCommandLineEnd();
    return parsedCommandLine;
  }
 @Override
 public ParserState onNonOption(String arg) {
   return option.onArgument(arg);
 }
 @Override
 public void onCommandLineEnd() {
   option.onComplete();
 }
  /**
   * Parses the given command-line.
   *
   * @param commandLine The command-line.
   * @return The parsed command line.
   * @throws org.gradle.cli.CommandLineArgumentException On parse failure.
   */
  public ParsedCommandLine parse(Iterable<String> commandLine) throws CommandLineArgumentException {
    ParsedCommandLine parsedCommandLine =
        new ParsedCommandLine(new HashSet<CommandLineOption>(optionsByString.values()));
    ParserState parseState = new BeforeFirstSubCommand(parsedCommandLine);
    for (String arg : commandLine) {
      if (parseState.maybeStartOption(arg)) {
        if (arg.equals("--")) {
          parseState = new AfterOptions(parsedCommandLine);
        } else if (arg.matches("--[^=]+")) {
          OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(2));
          parseState = parsedOption.onStartNextArg();
        } else if (arg.matches("--[^=]+=.*")) {
          int endArg = arg.indexOf('=');
          OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(2, endArg));
          parseState = parsedOption.onArgument(arg.substring(endArg + 1));
        } else if (arg.matches("-[^=]=.*")) {
          OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(1, 2));
          parseState = parsedOption.onArgument(arg.substring(3));
        } else {
          assert arg.matches("-[^-].*");
          String option = arg.substring(1);
          if (optionsByString.containsKey(option)) {
            OptionParserState parsedOption = parseState.onStartOption(arg, option);
            parseState = parsedOption.onStartNextArg();
          } else {
            String option1 = arg.substring(1, 2);
            OptionParserState parsedOption;
            if (optionsByString.containsKey(option1)) {
              parsedOption = parseState.onStartOption("-" + option1, option1);
              if (parsedOption.getHasArgument()) {
                parseState = parsedOption.onArgument(arg.substring(2));
              } else {
                parseState = parsedOption.onComplete();
                for (int i = 2; i < arg.length(); i++) {
                  String optionStr = arg.substring(i, i + 1);
                  parsedOption = parseState.onStartOption("-" + optionStr, optionStr);
                  parseState = parsedOption.onComplete();
                }
              }
            } else {
              if (allowUnknownOptions) {
                // if we are allowing unknowns, just pass through the whole arg
                parsedOption = parseState.onStartOption(arg, option);
                parseState = parsedOption.onComplete();
              } else {
                // We are going to throw a CommandLineArgumentException below, but want the message
                // to reflect that we didn't recognise the first char (i.e. the option specifier)
                parsedOption = parseState.onStartOption("-" + option1, option1);
                parseState = parsedOption.onComplete();
              }
            }
          }
        }
      } else {
        parseState = parseState.onNonOption(arg);
      }
    }

    parseState.onCommandLineEnd();
    return parsedCommandLine;
  }