docs: public CommandLine parse(Options options, String[] arguments, Properties properties, boolean stopAtNonOption)
              throws ParseException
      {
          // clear out the data in options in case it's been used before (CLI-71)
          for (Option opt : options.helpOptions())
          {
              opt.clearValues();
          }
          
          // clear the data from the groups
          for (OptionGroup group : options.getOptionGroups())
          {
              group.setSelected(null);
          }        
  
          // initialise members
          setOptions(options);
  
          cmd = new CommandLine();
  
          boolean eatTheRest = false;
  
          if (arguments == null)
          {
              arguments = new String[0];
          }
  
          List<String> tokenList = Arrays.asList(flatten(getOptions(), arguments, stopAtNonOption));
  
          ListIterator<String> iterator = tokenList.listIterator();
  
          // process each flattened token
          while (iterator.hasNext())
          {
              String t = iterator.next();
  
              // the value is the double-dash
              if ("--".equals(t))
              {
                  eatTheRest = true;
              }
  
              // the value is a single dash
              else if ("-".equals(t))
              {
                  if (stopAtNonOption)
                  {
                      eatTheRest = true;
                  }
                  else
                  {
                      cmd.addArg(t);
                  }
              }
  
              // the value is an option
              else if (t.startsWith("-"))
              {
                  if (stopAtNonOption && !getOptions().hasOption(t))
                  {
                      eatTheRest = true;
                      cmd.addArg(t);
                  }
                  else
                  {
                      processOption(t, iterator);
                  }
              }
  
              // the value is an argument
              else
              {
                  cmd.addArg(t);
  
                  if (stopAtNonOption)
                  {
                      eatTheRest = true;
                  }
              }
  
              // eat the remaining tokens
              if (eatTheRest)
              {
                  while (iterator.hasNext())
                  {
                      String str = iterator.next();
  
                      // ensure only one double-dash is added
                      if (!"--".equals(str))
                      {
                          cmd.addArg(str);
                      }
                  }
              }
          }
  
          processProperties(properties);
          checkRequiredOptions();
  
          return cmd;
      }