public static void Split(string str, IList <string> list, int options = 0)
        {
            StringBuilder commandBuffer = StringBuilderPool.NextAutoRecycleBuilder();

            bool insideDoubleQuotes = false;
            bool insideSingleQuotes = false;

            char ch = (char)0;
            char prevCh;

            for (int i = 0; i < str.Length;)
            {
                prevCh = ch;
                ch     = str[i++];

                if (ch == '&' && i < str.Length && str[i] == '&') // found command separator
                {
                    if (!insideDoubleQuotes && !insideSingleQuotes)
                    {
                        AddCommand(commandBuffer, list);
                        ++i; // skip second separator's char
                    }
                    else
                    {
                        commandBuffer.Append(ch);
                    }
                }
                else if (ch == DoubleQuote)
                {
                    commandBuffer.Append(ch);

                    if (insideDoubleQuotes)
                    {
                        insideDoubleQuotes = prevCh == EscapeSymbol;
                    }
                    else
                    {
                        insideDoubleQuotes = prevCh != EscapeSymbol;
                    }
                }
                else if (ch == SingleQuote)
                {
                    commandBuffer.Append(ch);
                    if (insideSingleQuotes)
                    {
                        insideSingleQuotes = prevCh == EscapeSymbol;
                    }
                    else
                    {
                        insideSingleQuotes = prevCh != EscapeSymbol;
                    }
                }
                else
                {
                    commandBuffer.Append(ch);
                }
            }

            if (insideDoubleQuotes && !HasOption(options, OPTION_IGNORE_MISSING_QUOTES))
            {
                throw new TokenizeException("Missing closing double quote");
            }

            if (insideSingleQuotes && !HasOption(options, OPTION_IGNORE_MISSING_QUOTES))
            {
                throw new TokenizeException("Missing closing single quote");
            }

            if (commandBuffer.Length > 0)
            {
                AddCommand(commandBuffer, list);
            }
        }
        public static void Tokenize(string str, IList <string> tokens, int options = 0)
        {
            StringBuilder tokenBuffer = StringBuilderPool.NextAutoRecycleBuilder();

            bool insideSingleQuotes = false;
            bool insideDoubleQuotes = false;
            bool shouldAddToken     = true;

            char ch = (char)0;
            char prevCh;

            for (int i = 0; i < str.Length;)
            {
                prevCh = ch;
                ch     = str[i++];

                if (char.IsWhiteSpace(ch))
                {
                    if (!insideDoubleQuotes && !insideSingleQuotes && shouldAddToken)
                    {
                        AddToken(tokenBuffer, tokens);
                    }
                    else
                    {
                        tokenBuffer.Append(ch);
                    }
                }
                else if (ch == DoubleQuote)
                {
                    if (insideSingleQuotes)
                    {
                        tokenBuffer.Append(ch);
                    }
                    else
                    {
                        if (insideDoubleQuotes)
                        {
                            if (prevCh == EscapeSymbol)
                            {
                                tokenBuffer.Append(ch);
                            }
                            else
                            {
                                if (shouldAddToken)
                                {
                                    AddToken(tokenBuffer, tokens, true);
                                }
                                else
                                {
                                    tokenBuffer.Append(ch);
                                }

                                shouldAddToken     = true;
                                insideDoubleQuotes = false;
                            }
                        }
                        else
                        {
                            shouldAddToken = char.IsWhiteSpace(prevCh) || prevCh == (char)0;
                            if (!shouldAddToken)
                            {
                                tokenBuffer.Append(ch);
                            }
                            insideDoubleQuotes = true;
                        }
                    }
                }
                else if (ch == SingleQuote)
                {
                    if (insideDoubleQuotes)
                    {
                        tokenBuffer.Append(ch);
                    }
                    else
                    {
                        if (insideSingleQuotes)
                        {
                            if (prevCh == EscapeSymbol)
                            {
                                tokenBuffer.Append(ch);
                            }
                            else
                            {
                                if (shouldAddToken)
                                {
                                    AddToken(tokenBuffer, tokens, true);
                                }
                                else
                                {
                                    tokenBuffer.Append(ch);
                                }

                                shouldAddToken     = true;
                                insideSingleQuotes = false;
                            }
                        }
                        else
                        {
                            shouldAddToken = char.IsWhiteSpace(prevCh) || prevCh == (char)0;
                            if (!shouldAddToken)
                            {
                                tokenBuffer.Append(ch);
                            }
                            insideSingleQuotes = true;
                        }
                    }
                }
                else
                {
                    tokenBuffer.Append(ch);
                }
            }

            if (insideDoubleQuotes && !HasOption(options, OPTION_IGNORE_MISSING_QUOTES))
            {
                throw new TokenizeException("Missing closing double quote: " + str);
            }

            if (insideSingleQuotes && !HasOption(options, OPTION_IGNORE_MISSING_QUOTES))
            {
                throw new TokenizeException("Missing closing single quote: " + str);
            }

            AddToken(tokenBuffer, tokens);
        }