/// <summary>
 /// Adds a CommandOption along with its value
 /// </summary>
 /// <param name="option"></param>
 /// <param name="value"></param>
 public void AddOption(CommandOption option, CommandOptionValue value)
 {
     _values[option] = value;
 }
        /// <summary>
        /// Parse all the command line arguments.
        /// </summary>
        /// <param name="options"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static CommandOptions ParseArguments(
            IList <CommandOption> options, string[] arguments)
        {
            CommandOptions values = new CommandOptions();

            for (int i = 0; i < arguments.Length; i++)
            {
                // Collect arguments that are not attached to a switch. This is currently always the function name.
                if (!arguments[i].StartsWith("-"))
                {
                    values.Arguments.Add(arguments[i]);
                }
                else
                {
                    var option = FindCommandOption(options, arguments[i]);
                    if (option != null)
                    {
                        var value = new CommandOptionValue();

                        if (option.ValueType != CommandOption.CommandOptionValueType.NoValue)
                        {
                            if (i + 1 >= arguments.Length)
                            {
                                throw new ToolsException($"Argument {arguments[i]} must be followed by a value", ToolsException.CommonErrorCode.CommandLineParseError);
                            }

                            switch (option.ValueType)
                            {
                            case CommandOption.CommandOptionValueType.StringValue:
                            case CommandOption.CommandOptionValueType.JsonValue:
                                value.StringValue = arguments?[i + 1];
                                break;

                            case CommandOption.CommandOptionValueType.CommaDelimitedList:
                                value.StringValues = arguments?[i + 1].SplitByComma();
                                break;

                            case CommandOption.CommandOptionValueType.KeyValuePairs:
                                value.KeyValuePairs = Utilities.ParseKeyValueOption(arguments[i + 1]);
                                break;

                            case CommandOption.CommandOptionValueType.IntValue:
                                int iv;
                                if (!int.TryParse(arguments?[i + 1], out iv))
                                {
                                    throw new Exception($"Argument {arguments?[i]} expects an integer value but received an {arguments?[i + 1]}");
                                }
                                value.IntValue = iv;
                                break;

                            case CommandOption.CommandOptionValueType.BoolValue:
                                bool bv;
                                if (!bool.TryParse(arguments?[i + 1], out bv))
                                {
                                    throw new Exception($"Argument {arguments?[i]} expects either {bool.TrueString} or {bool.FalseString} value but received an {arguments?[i + 1]}");
                                }
                                value.BoolValue = bv;
                                break;
                            }
                            i++;
                        }

                        values.AddOption(option, value);
                    }
                }
            }

            return(values);
        }