public ParserResult ParseArguments(string[] args, bool errorOnUnrecognizedArgument = false)
        {
            ParserResult result = new ParserResult();

            for (int i = 0; i < args.Length; i++)
            {
                string argumentName = args[i];

                if (argumentName.StartsWith(DefaultFullArgumentNamePrefix))
                {
                    string shortenedArgumentName = argumentName.Substring(DefaultFullArgumentNamePrefix.Length);

                    ICommandLineArgument argument;
                    if (!arguments.TryGetValue(shortenedArgumentName, out argument) && errorOnUnrecognizedArgument)
                    {
                        result.Errors.Add(new ParserError
                        {
                            ErrorType    = ParserErrorType.UnrecognizedArgument,
                            ErrorDetails = $"An unrecognized argument '{argumentName}' was provided."
                        });
                    }

                    if (argument == null)
                    {
                        continue;
                    }

                    CommandLineArgument concreteArgument = argument.ToCommandLineArgument();
                    if (argument.IsSwitch)
                    {
                        concreteArgument.Value = true;
                    }
                    else
                    {
                        ArgumentParser parser        = argumentTypeParsers[argument.ArgumentType];
                        string         argumentValue = args[++i];

                        try
                        {
                            concreteArgument.Value = parser.Parse(argumentValue);
                        }
                        catch (Exception ex)
                        {
                            result.Errors.Add(new ParserError
                            {
                                ErrorType       = ParserErrorType.InvalidInput,
                                ErrorDetails    = $"An Exception occurred when parsing {argument.Name}.",
                                ArgumentInput   = argumentValue,
                                Argument        = argument,
                                ParserException = ex
                            });
                        }
                    }

                    if (requiredArguments.Contains(shortenedArgumentName))
                    {
                        requiredArguments.Remove(shortenedArgumentName);
                    }
                }
            }

            foreach (var missingRequiredArgument in requiredArguments)
            {
                result.Errors.Add(new ParserError
                {
                    ErrorType = ParserErrorType.MissingRequiredParameter,
                    Argument  = arguments[missingRequiredArgument]
                });
            }

            result.Arguments = arguments;
            return(result);
        }