base/common/src/main/com/thesett/common/util/CommandLineParser.java
public Properties parseCommandLine(String[] args) throws IllegalArgumentException
    {
        Properties options = new Properties();

        // Used to keep count of the current 'free' argument.
        int free = 1;

        // Used to indicate that the most recently parsed option is expecting arguments.
        boolean expectingArgs = false;

        // The option that is expecting arguments from the next element of the command line.
        String optionExpectingArgs = null;

        // Used to indicate that the most recently parsed option is a duplicate and should be ignored.
        // boolean ignore = false;

        // Create the regular expression matcher for the command line options.
        String regexp = "^(";
        int optionsAdded = 0;

        for (Iterator<String> i = optionMap.keySet().iterator(); i.hasNext();)
        {
            String nextOption = i.next();

            // Check that the option is not a free argument definition.
            boolean notFree = false;

            try
            {
                Integer.parseInt(nextOption);
            }
            catch (NumberFormatException e)
            {
                notFree = true;
            }

            // Add the option to the regular expression matcher if it is not a free argument definition.
            if (notFree)
            {
                regexp += nextOption + (i.hasNext() ? "|" : "");
                optionsAdded++;
            }
        }

        // There has to be more that one option in the regular expression or else the compiler complains that the close
        // cannot be nullable if the '?' token is used to make the matched option string optional.
        regexp += ")" + ((optionsAdded > 0) ? "?" : "") + "(.*)";

        Pattern pattern = Pattern.compile(regexp);

        // Loop through all the command line arguments.
        for (String arg1 : args)
        {
            // Check if the next command line argument begins with a '-' character and is therefore the start of
            // an option.
            if (arg1.startsWith("-"))
            {
                // Extract the value of the option without the leading '-'.
                String arg = arg1.substring(1);

                // Match up to the longest matching option.
                optionMatcher = pattern.matcher(arg);
                optionMatcher.matches();

                String matchedOption = optionMatcher.group(1);

                // Match any argument directly appended onto the longest matching option.
                String matchedArg = optionMatcher.group(2);

                // Check that a known option was matched.
                if ((matchedOption != null) && !"".equals(matchedOption))
                {
                    // Get the command line option information for the matched option.
                    CommandLineOption optionInfo = optionMap.get(matchedOption);

                    // Check if this option is expecting arguments.
                    if (optionInfo.expectsArgs)
                    {
                        // The option is expecting arguments so swallow the next command line argument as an
                        // argument to this option.
                        expectingArgs = true;
                        optionExpectingArgs = matchedOption;

                        // In the mean time set this options argument to the empty string in case no argument is ever
                        // supplied.
                        // options.put(matchedOption, "");
                    }

                    // Check if the option was matched on its own and is a flag in which case set that flag.
                    if ("".equals(matchedArg) && !optionInfo.expectsArgs)
                    {
                        options.put(matchedOption, "true");
                    }

                    // The option was matched as a substring with its argument appended to it or is a flag that is
                    // condensed together with other flags.
                    else if (!"".equals(matchedArg))
                    {
                        // Check if the option is a flag and therefore is allowed to be condensed together
                        // with other flags.
                        if (!optionInfo.expectsArgs)
                        {
                            // Set the first matched flag.
                            options.put(matchedOption, "true");

                            // Repeat the longest matching process on the remainder but ensure that the remainder
                            // consists only of flags as only flags may be condensed together in this fashion.
                            do
                            {
                                // Match the remainder against the options.
                                optionMatcher = pattern.matcher(matchedArg);
                                optionMatcher.matches();

                                matchedOption = optionMatcher.group(1);
                                matchedArg = optionMatcher.group(2);

                                // Check that an option was matched.
                                if (matchedOption != null)
                                {
                                    // Get the command line option information for the next matched option.
                                    optionInfo = optionMap.get(matchedOption);

                                    // Ensure that the next option is a flag or raise an error if not.
                                    if (optionInfo.expectsArgs)
                                    {
                                        parsingErrors.add("Option " + matchedOption +
                                            " cannot be combined with flags.\n");
                                    }

                                    options.put(matchedOption, "true");
                                }

                                // The remainder could not be matched against a flag it is either an unknown flag
                                // or an illegal argument to a flag.
                                else
                                {
                                    parsingErrors.add("Illegal argument to a flag in the option " + arg + "\n");

                                    break;
                                }
                            }
                            // Continue until the remainder of the argument has all been matched with flags.
                            while (!"".equals(matchedArg));
                        }

                        // The option is expecting an argument, so store the unmatched portion against it
                        // as its argument.
                        else
                        {
                            // Check the arguments format is correct against any specified format.
                            checkArgumentFormat(optionInfo, matchedArg);

                            // Store the argument against its option (regardless of its format).
                            options.put(matchedOption, matchedArg);

                            // The argument to this flag has already been supplied to it. Do not swallow the
                            // next command line argument as an argument to this flag.
                            expectingArgs = false;
                        }
                    }
                }
                else // No matching option was found.
                {
                    // Add this to the list of parsing errors if errors on unkowns is being used.
                    if (errorsOnUnknowns)
                    {
                        parsingErrors.add("Option " + matchedOption + " is not a recognized option.\n");
                    }
                }
            }

            // The command line argument did not being with a '-' so it is an argument to the previous flag or it
            // is a free argument.
            else
            {
                // Check if a previous flag is expecting to swallow this next argument as its argument.
                if (expectingArgs)
                {
                    // Get the option info for the option waiting for arguments.
                    CommandLineOption optionInfo = optionMap.get(optionExpectingArgs);

                    // Check the arguments format is correct against any specified format.
                    checkArgumentFormat(optionInfo, arg1);

                    // Store the argument against its option (regardless of its format).
                    options.put(optionExpectingArgs, arg1);

                    // Clear the expecting args flag now that the argument has been swallowed.
                    expectingArgs = false;
                    optionExpectingArgs = null;
                }

                // This command line option is not an argument to any option. Add it to the set of 'free' options.
                else
                {
                    // Get the option info for the free option, if there is any.
                    CommandLineOption optionInfo = optionMap.get(Integer.toString(free));

                    if (optionInfo != null)
                    {
                        // Check the arguments format is correct against any specified format.
                        checkArgumentFormat(optionInfo, arg1);
                    }

                    // Add to the list of free options.
                    options.put(Integer.toString(free), arg1);

                    // Move on to the next free argument.
                    free++;
                }
            }
        }

        // Scan through all the specified options to check that all mandatory options have been set and that all flags
        // that were not set are set to false in the set of properties.
        for (CommandLineOption optionInfo : optionMap.values())
        {
            // Check if this is a flag.
            if (!optionInfo.expectsArgs)
            {
                // Check if the flag is not set in the properties and set it to false if so.
                if (!options.containsKey(optionInfo.option))
                {
                    options.put(optionInfo.option, "false");
                }
            }

            // Check if this is a mandatory option and was not set.
            else if (optionInfo.mandatory && !options.containsKey(optionInfo.option))
            {
                // Create an error for the missing option.
                parsingErrors.add("Option " + optionInfo.option + " is mandatory but not was not specified.\n");
            }
        }

        // Check if there were any errors.
        if (!parsingErrors.isEmpty())
        {
            // Throw an illegal argument exception to signify that there were parsing errors.
            throw new IllegalArgumentException();
        }

        // Convert any name/value pairs in the free arguments into properties in the parsed options.
        trailingProperties = takeFreeArgsAsProperties(options, 1);

        parsedProperties = options;

        return options;
    }
public Properties parseCommandLine(String[] args) throws IllegalArgumentException
    {
        Properties options = new Properties();

        // Used to keep count of the current 'free' argument.
        int free = 1;

        // Used to indicate that the most recently parsed option is expecting arguments.
        boolean expectingArgs = false;

        // The option that is expecting arguments from the next element of the command line.
        String optionExpectingArgs = null;

        // Used to indicate that the most recently parsed option is a duplicate and should be ignored.
        // boolean ignore = false;

        // Create the regular expression matcher for the command line options.
        String regexp = "^(";
        int optionsAdded = 0;

        for (Iterator<String> i = optionMap.keySet().iterator(); i.hasNext();)
        {
            String nextOption = i.next();

            // Check that the option is not a free argument definition.
            boolean notFree = false;

            try
            {
                Integer.parseInt(nextOption);
            }
            catch (NumberFormatException e)
            {
                notFree = true;
            }

            // Add the option to the regular expression matcher if it is not a free argument definition.
            if (notFree)
            {
                regexp += nextOption + (i.hasNext() ? "|" : "");
                optionsAdded++;
            }
        }

        // There has to be more that one option in the regular expression or else the compiler complains that the close
        // cannot be nullable if the '?' token is used to make the matched option string optional.
        regexp += ")" + ((optionsAdded > 0) ? "?" : "") + "(.*)";

        Pattern pattern = Pattern.compile(regexp);

        // Loop through all the command line arguments.
        for (String arg1 : args)
        {
            // Check if the next command line argument begins with a '-' character and is therefore the start of
            // an option.
            if (arg1.startsWith("-"))
            {
                // Extract the value of the option without the leading '-'.
                String arg = arg1.substring(1);

                // Match up to the longest matching option.
                optionMatcher = pattern.matcher(arg);
                optionMatcher.matches();

                String matchedOption = optionMatcher.group(1);

                // Match any argument directly appended onto the longest matching option.
                String matchedArg = optionMatcher.group(2);

                // Check that a known option was matched.
                if ((matchedOption != null) && !"".equals(matchedOption))
                {
                    // Get the command line option information for the matched option.
                    CommandLineOption optionInfo = optionMap.get(matchedOption);

                    // Check if this option is expecting arguments.
                    if (optionInfo.expectsArgs)
                    {
                        // The option is expecting arguments so swallow the next command line argument as an
                        // argument to this option.
                        expectingArgs = true;
                        optionExpectingArgs = matchedOption;

                        // In the mean time set this options argument to the empty string in case no argument is ever
                        // supplied.
                        // options.put(matchedOption, "");
                    }

                    // Check if the option was matched on its own and is a flag in which case set that flag.
                    if ("".equals(matchedArg) && !optionInfo.expectsArgs)
                    {
                        options.put(matchedOption, "true");
                    }

                    // The option was matched as a substring with its argument appended to it or is a flag that is
                    // condensed together with other flags.
                    else if (!"".equals(matchedArg))
                    {
                        // Check if the option is a flag and therefore is allowed to be condensed together
                        // with other flags.
                        if (!optionInfo.expectsArgs)
                        {
                            // Set the first matched flag.
                            options.put(matchedOption, "true");

                            // Repeat the longest matching process on the remainder but ensure that the remainder
                            // consists only of flags as only flags may be condensed together in this fashion.
                            do
                            {
                                // Match the remainder against the options.
                                optionMatcher = pattern.matcher(matchedArg);
                                optionMatcher.matches();

                                matchedOption = optionMatcher.group(1);
                                matchedArg = optionMatcher.group(2);

                                // Check that an option was matched.
                                if (matchedOption != null)
                                {
                                    // Get the command line option information for the next matched option.
                                    optionInfo = optionMap.get(matchedOption);

                                    // Ensure that the next option is a flag or raise an error if not.
                                    if (optionInfo.expectsArgs)
                                    {
                                        parsingErrors.add("Option " + matchedOption +
                                            " cannot be combined with flags.\n");
                                    }

                                    options.put(matchedOption, "true");
                                }

                                // The remainder could not be matched against a flag it is either an unknown flag
                                // or an illegal argument to a flag.
                                else
                                {
                                    parsingErrors.add("Illegal argument to a flag in the option " + arg + "\n");

                                    break;
                                }
                            }
                            // Continue until the remainder of the argument has all been matched with flags.
                            while (!"".equals(matchedArg));
                        }

                        // The option is expecting an argument, so store the unmatched portion against it
                        // as its argument.
                        else
                        {
                            // Check the arguments format is correct against any specified format.
                            checkArgumentFormat(optionInfo, matchedArg);

                            // Store the argument against its option (regardless of its format).
                            options.put(matchedOption, matchedArg);

                            // The argument to this flag has already been supplied to it. Do not swallow the
                            // next command line argument as an argument to this flag.
                            expectingArgs = false;
                        }
                    }
                }
                else // No matching option was found.
                {
                    // Add this to the list of parsing errors if errors on unkowns is being used.
                    if (errorsOnUnknowns)
                    {
                        parsingErrors.add("Option " + matchedOption + " is not a recognized option.\n");
                    }
                }
            }

            // The command line argument did not being with a '-' so it is an argument to the previous flag or it
            // is a free argument.
            else
            {
                // Check if a previous flag is expecting to swallow this next argument as its argument.
                if (expectingArgs)
                {
                    // Get the option info for the option waiting for arguments.
                    CommandLineOption optionInfo = optionMap.get(optionExpectingArgs);

                    // Check the arguments format is correct against any specified format.
                    checkArgumentFormat(optionInfo, arg1);

                    // Store the argument against its option (regardless of its format).
                    options.put(optionExpectingArgs, arg1);

                    // Clear the expecting args flag now that the argument has been swallowed.
                    expectingArgs = false;
                    optionExpectingArgs = null;
                }

                // This command line option is not an argument to any option. Add it to the set of 'free' options.
                else
                {
                    // Get the option info for the free option, if there is any.
                    CommandLineOption optionInfo = optionMap.get(Integer.toString(free));

                    if (optionInfo != null)
                    {
                        // Check the arguments format is correct against any specified format.
                        checkArgumentFormat(optionInfo, arg1);
                    }

                    // Add to the list of free options.
                    options.put(Integer.toString(free), arg1);

                    // Move on to the next free argument.
                    free++;
                }
            }
        }

        // Scan through all the specified options to check that all mandatory options have been set and that all flags
        // that were not set are set to false in the set of properties.
        for (CommandLineOption optionInfo : optionMap.values())
        {
            // Check if this is a flag.
            if (!optionInfo.expectsArgs)
            {
                // Check if the flag is not set in the properties and set it to false if so.
                if (!options.containsKey(optionInfo.option))
                {
                    options.put(optionInfo.option, "false");
                }
            }

            // Check if this is a mandatory option and was not set.
            else if (optionInfo.mandatory && !options.containsKey(optionInfo.option))
            {
                // Create an error for the missing option.
                parsingErrors.add("Option " + optionInfo.option + " is mandatory but not was not specified.\n");
            }
        }

        // Check if there were any errors.
        if (!parsingErrors.isEmpty())
        {
            // Throw an illegal argument exception to signify that there were parsing errors.
            throw new IllegalArgumentException();
        }

        // Convert any name/value pairs in the free arguments into properties in the parsed options.
        trailingProperties = takeFreeArgsAsProperties(options, 1);

        parsedProperties = options;

        return options;
    }
Parses a set of command line arguments into a set of properties, keyed by the argument flag. The free arguments
are keyed by integers as strings starting at "1" and then "2", ... and so on.

<p/>See the class level comment for a description of the parsing rules.

@param  args The command line arguments.

@return The arguments as a set of properties.

@throws IllegalArgumentException If the command line cannot be parsed against its specification. If this
exception is thrown a call to {@link #getErrors} will provide a diagnostic of
the command line errors.