private void InitializeParameters()
        {
            var args = new List <Parameter>();

            var state = ParseState.Normal;

            var argName      = new StringBuilder();
            var defaultValue = new StringBuilder();
            var kind         = ParameterType.Required;

            void InternalReset()
            {
                state = ParseState.Normal;
                argName.Clear();
                defaultValue.Clear();
                kind = ParameterType.Required;
            }

            for (var index = 0; index < _parameterDescription.Length; index++)
            {
                var c = _parameterDescription[index];

                switch (c)
                {
                case LeftBracket:
                    if (state != ParseState.Normal)
                    {
                        throw new CommandParseException($"invalid {c} here", _parameterDescription, index);
                    }
                    state = ParseState.InsideBracket;
                    continue;

                case RightBracket:
                    if (state != ParseState.InsideBracket)
                    {
                        throw new CommandParseException($"invalid {c} here", _parameterDescription, index);
                    }
                    if (argName.Length == 0)
                    {
                        throw new CommandParseException("Argument must have a name", _parameterDescription, index);
                    }
                    args.Add(new Parameter(kind, argName.ToString(), defaultValue.ToString()));
                    InternalReset();
                    state = ParseState.Normal;
                    continue;
                }

                switch (state)
                {
                case ParseState.Normal:
                    // do nothing
                    break;

                case ParseState.InsideBracket:
                    if (VanRegex.IsMatch(c.ToString()))
                    {
                        argName.Append(c);
                    }
                    else
                    {
                        switch (c)
                        {
                        case DefaultValueRepresentation:
                            while ((c = _parameterDescription[++index]) != RightBracket)
                            {
                                defaultValue.Append(c);
                            }
                            index--;
                            kind = ParameterType.DefaultValue;
                            continue;

                        case SpecialValueRepresentation:                                         // special value
                            var special = new StringBuilder();
                            while ((c = _parameterDescription[++index]) != RightBracket)
                            {
                                special.Append(c);
                            }
                            index--;
                            argName = special;
                            switch (special.ToString().Trim())
                            {
                            case "Player":
                                kind = ParameterType.PlayerName;
                                continue;
                            }
                            continue;

                        case OptionalRepresentation:                                         // optional
                            if (argName.Length != 0)
                            {
                                throw new CommandParseException("Wrong position for " + OptionalRepresentation, _parameterDescription, index);
                            }
                            kind = ParameterType.NotRequired;
                            continue;

                        default:
                            throw new CommandParseException("Invalid character " + c, _parameterDescription, index);
                        }
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            if (state != ParseState.Normal)
            {
                throw new CommandParseException("Unexpected ending", _parameterDescription, _parameterDescription.Length - 1);
            }

            Parameters        = args.ToArray();
            _fewestParamCount = (byte)Parameters.Count(x => x.Type == ParameterType.Required);
        }
        private void InitializeCommandLines()
        {
            var lines = new List <string>();

            foreach (var line in _commandLines)
            {
                var state   = ParseState.Normal;
                var argName = new StringBuilder();

                var format = new StringBuilder();

                foreach (var c in line)
                {
                    switch (c)
                    {
                    case LeftBracket:
                        if (state != ParseState.Normal)
                        {
                            throw new CommandParseException($"invalid {c} here");
                        }
                        state = ParseState.InsideBracket;
                        continue;

                    case RightBracket:
                        if (state != ParseState.InsideBracket)
                        {
                            throw new CommandParseException($"invalid {c} here");
                        }
                        var name = argName.ToString();
                        if (name.Length == 0)
                        {
                            throw new CommandParseException("Parameter must have a name");
                        }

                        var formatIndex = Array.FindIndex(Parameters, x => x.Name.Equals(name, StringComparison.Ordinal));
                        if (formatIndex == -1)
                        {
                            throw new CommandParseException("Undeclared parameter: " + name);
                        }
                        format.AppendFormat("{{{0}}}", formatIndex);

                        argName.Clear();
                        state = ParseState.Normal;
                        continue;
                    }

                    switch (state)
                    {
                    case ParseState.Normal:
                        format.Append(c);
                        break;

                    case ParseState.InsideBracket:
                        if (VanRegex.IsMatch(c.ToString()))
                        {
                            argName.Append(c);
                        }
                        break;
                    }
                }

                lines.Add(format.ToString());
            }

            FormatLines = lines.ToArray();
        }