@Override
    public ParserState onComplete() {
      if (getHasArgument() && values.isEmpty()) {
        throw new CommandLineArgumentException(
            String.format("No argument was provided for command-line option '%s'.", optionString));
      }

      ParsedCommandLineOption parsedOption = commandLine.addOption(optionString.option, option);
      if (values.size() + parsedOption.getValues().size() > 1
          && !option.getAllowsMultipleArguments()) {
        throw new CommandLineArgumentException(
            String.format(
                "Multiple arguments were provided for command-line option '%s'.", optionString));
      }
      for (String value : values) {
        parsedOption.addArgument(value);
      }
      if (option.getDeprecationWarning() != null) {
        deprecationPrinter.println(
            "The " + optionString + " option is deprecated - " + option.getDeprecationWarning());
      }

      for (CommandLineOption otherOption : option.getGroupWith()) {
        commandLine.removeOption(otherOption);
      }

      return state;
    }
 /**
  * Specifies that the given set of options are mutually-exclusive. Only one of the given options
  * will be selected. The parser ignores all but the last of these options.
  */
 public CommandLineParser allowOneOf(String... options) {
   Set<CommandLineOption> commandLineOptions = new HashSet<CommandLineOption>();
   for (String option : options) {
     commandLineOptions.add(optionsByString.get(option));
   }
   for (CommandLineOption commandLineOption : commandLineOptions) {
     commandLineOption.groupWith(commandLineOptions);
   }
   return this;
 }
 @Override
 public ParserState onStartNextArg() {
   if (option.getAllowsArguments() && values.isEmpty()) {
     return new MissingOptionArgState(this);
   }
   return onComplete();
 }
 /**
  * Defines a new option. By default, the option takes no arguments and has no description.
  *
  * @param options The options values.
  * @return The option, which can be further configured.
  */
 public CommandLineOption option(String... options) {
   for (String option : options) {
     if (optionsByString.containsKey(option)) {
       throw new IllegalArgumentException(
           String.format("Option '%s' is already defined.", option));
     }
     if (option.startsWith("-")) {
       throw new IllegalArgumentException(
           String.format("Cannot add option '%s' as an option cannot start with '-'.", option));
     }
   }
   CommandLineOption option = new CommandLineOption(Arrays.asList(options));
   for (String optionStr : option.getOptions()) {
     optionsByString.put(optionStr, option);
   }
   return option;
 }
  /**
   * Prints a usage message to the given stream.
   *
   * @param out The output stream to write to.
   */
  public void printUsage(Appendable out) {
    Formatter formatter = new Formatter(out);
    Set<CommandLineOption> orderedOptions = new TreeSet<CommandLineOption>(new OptionComparator());
    orderedOptions.addAll(optionsByString.values());
    Map<String, String> lines = new LinkedHashMap<String, String>();
    for (CommandLineOption option : orderedOptions) {
      Set<String> orderedOptionStrings = new TreeSet<String>(new OptionStringComparator());
      orderedOptionStrings.addAll(option.getOptions());
      List<String> prefixedStrings = new ArrayList<String>();
      for (String optionString : orderedOptionStrings) {
        if (optionString.length() == 1) {
          prefixedStrings.add("-" + optionString);
        } else {
          prefixedStrings.add("--" + optionString);
        }
      }

      String key = join(prefixedStrings, ", ");
      String value = option.getDescription();
      if (value == null || value.length() == 0) {
        value = "";
      }

      lines.put(key, value);
    }
    int max = 0;
    for (String optionStr : lines.keySet()) {
      max = Math.max(max, optionStr.length());
    }
    for (Map.Entry<String, String> entry : lines.entrySet()) {
      if (entry.getValue().length() == 0) {
        formatter.format("%s%n", entry.getKey());
      } else {
        formatter.format("%-" + max + "s  %s%n", entry.getKey(), entry.getValue());
      }
    }
    formatter.flush();
  }
 public int compare(CommandLineOption option1, CommandLineOption option2) {
   String min1 = Collections.min(option1.getOptions(), new OptionStringComparator());
   String min2 = Collections.min(option2.getOptions(), new OptionStringComparator());
   return new CaseInsensitiveStringComparator().compare(min1, min2);
 }
 @Override
 public boolean getHasArgument() {
   return option.getAllowsArguments();
 }