/// <summary>
        /// Get value of the switch.
        /// </summary>
        public T GetValue <T>
        (
            [NotNull] string name,
            [CanBeNull] T defaultValue
        )
        {
            Code.NotNullNorEmpty(name, "name");

            CommandLineSwitch found = GetSwitch(name);
            T result = ReferenceEquals(found, null)
                ? defaultValue
                : ConversionUtility.ConvertTo <T>(found.Value);

            return(result);
        }
        public string GetValue
        (
            [NotNull] string name,
            [CanBeNull] string defaultValue
        )
        {
            Code.NotNullNorEmpty(name, "name");

            CommandLineSwitch found  = GetSwitch(name);
            string            result = ReferenceEquals(found, null)
                ? defaultValue
                : found.Value;

            return(result);
        }
        private CommandLineSwitch _ParseSwitch
        (
            string text
        )
        {
            if (text.Length < 2)
            {
                Log.Error
                (
                    "CommandLineParser::_ParseSwitch: "
                    + "premature end of text"
                );

                throw new ArgumentException();
            }

            CommandLineSwitch result = new CommandLineSwitch();

            text = text.Substring(1);
            if (text.ContainsCharacter(CommandLineSettings.ValueSeparator))
            {
                char[] separators
                    = { CommandLineSettings.ValueSeparator };

                string[] parts = StringUtility.SplitString(text, separators, 2);

                if (string.IsNullOrEmpty(parts[0]) ||
                    string.IsNullOrEmpty(parts[1]))
                {
                    Log.Error
                    (
                        "CommandLineParser::_ParseSwitch: "
                        + "empty switch value"
                    );

                    throw new ArgumentException();
                }
                result.Name  = parts[0];
                result.Value = parts[1];
            }
            else
            {
                result.Name = text;
            }


            return(result);
        }
        public ParsedCommandLine AddSwitch
        (
            [NotNull] string name
        )
        {
            Code.NotNullNorEmpty(name, "name");

            CommandLineSwitch item = GetSwitch(name);

            if (ReferenceEquals(item, null))
            {
                item = new CommandLineSwitch(name);
                Switches.Add(item);
            }

            return(this);
        }
        public string[] GetValues
        (
            [NotNull] string name,
            [NotNull] string[] defaultValue
        )
        {
            Code.NotNullNorEmpty(name, "name");
            Code.NotNull(defaultValue, "defaultValue");

            CommandLineSwitch found = GetSwitch(name);

            string[] result = found == null
                ? defaultValue
                : found.Values.ToArray();

            return(result);
        }
        public ParsedCommandLine AddSwitch
        (
            [NotNull] CommandLineSwitch otherSwitch
        )
        {
            Code.NotNull(otherSwitch, "otherSwitch");

            CommandLineSwitch thisSwitch
                = GetSwitch(otherSwitch.Name);

            if (ReferenceEquals(thisSwitch, null))
            {
                Switches.Add(otherSwitch);
            }
            else
            {
                foreach (string value in otherSwitch.Values)
                {
                    thisSwitch.AddValue(value);
                }
            }

            return(this);
        }
        public ParsedCommandLine Parse
        (
            [NotNull][ItemNotNull] string[] arguments
        )
        {
            Code.NotNull(arguments, "arguments");

            ParsedCommandLine result = new ParsedCommandLine();

            foreach (string argument in arguments)
            {
                if (string.IsNullOrEmpty(argument))
                {
                    Log.Error
                    (
                        "CommandLineParser::Parse: "
                        + "empty argument"
                    );

                    throw new ArgumentException();
                }

                char firstChar = argument[0];
                if (firstChar == CommandLineSettings.ArgumentDelimiter)
                {
                    if (argument.Length == 1)
                    {
                        Log.Error
                        (
                            "CommandLineParser::Parse: "
                            + "premature end of argument"
                        );

                        throw new ArgumentException();
                    }
                    if (argument[argument.Length - 1] != '"')
                    {
                        Log.Error
                        (
                            "CommandLineParser::Parse: "
                            + "unclosed colon"
                        );

                        throw new ArgumentException();
                    }

                    string trimmed = argument.Substring(1, argument.Length - 2);
                    if (trimmed.Length == 0)
                    {
                        result.PositionalArguments.Add(string.Empty);
                        continue;
                    }

                    char secondChar = trimmed[0];
                    if (secondChar == CommandLineSettings.ResponsePrefix)
                    {
#if !WINMOBILE && !PocketPC
                        string            fileName = trimmed.Substring(1);
                        ParsedCommandLine inner    = ParseFile(fileName);
                        result.Merge(inner);
#endif
                    }
                    else if (secondChar == CommandLineSettings.SwitchPrefix)
                    {
                        CommandLineSwitch item = _ParseSwitch(trimmed);
                        result.AddSwitch(item);
                    }
                    else
                    {
                        result.PositionalArguments.Add(argument);
                    }
                }
                else if (firstChar == CommandLineSettings.ResponsePrefix)
                {
#if !WINMOBILE && !PocketPC
                    string            fileName = argument.Substring(1);
                    ParsedCommandLine inner    = ParseFile(fileName);
                    result.Merge(inner);
#endif
                }
                else if (firstChar == CommandLineSettings.SwitchPrefix)
                {
                    CommandLineSwitch item = _ParseSwitch(argument);
                    result.AddSwitch(item);
                }
                else
                {
                    result.PositionalArguments.Add(argument);
                }
            }

            return(result);
        }