private static void MatchNormal(string data, ref int pos, int end)
        {
            for (; pos < end; pos++)
            {
                switch (data[pos])
                {
                case '\'':
                    return;

                case '\"':
                    return;

                case '/':
                    if (end > pos + 1)
                    {
                        switch (data[pos + 1])
                        {
                        case '/':
                        case '*':
                            return;
                        }
                    }
                    break;

                case '<':
                    if (ParseMethods.SubstringMatch(data, pos, end, "<!--"))
                    {
                        return;
                    }
                    break;

                case '-':
                    if (ParseMethods.SubstringMatch(data, pos, end, "-->"))
                    {
                        return;
                    }
                    break;

                case 'u':
                case 'U':
                    if (ParseMethods.SubstringMatchIgnoreCase(data, pos, end, "url("))
                    {
                        return;
                    }
                    break;

                case '@':
                    if (ParseMethods.SubstringMatchIgnoreCase(data, pos, end, "@import"))
                    {
                        return;
                    }
                    break;
                }
            }
        }
        private static void MatchImport(string data, ref int pos, int end, out int literalPos, out int literalEnd, out char quotChar)
        {
            literalPos = pos;
            literalEnd = pos;
            quotChar   = (char)0;

            // skip (illegal) leading whitespace, e.g. url( http://www.microsoft.com)
            MatchWhitespace(data, ref pos, end);

            if (pos >= end)
            {
                return;
            }

            if (ParseMethods.SubstringMatchIgnoreCase(data, pos, end, "url("))
            {
                pos += 4;
                MatchUrl(data, ref pos, end, out literalPos, out literalEnd, out quotChar);
                ParseMethods.MatchUntilChar(';', true, data, ref pos, end);
                return;
            }

            switch (data[pos++])
            {
            case '\'':
                quotChar   = '\'';
                literalPos = pos;
                ParseMethods.MatchSingleQuotedLiteral(data, ref pos, end, out literalEnd);
                MatchWhitespace(data, ref pos, end);
                ParseMethods.MatchUntilChar(';', true, data, ref pos, end);
                break;

            case '"':
                quotChar   = '"';
                literalPos = pos;
                ParseMethods.MatchDoubleQuotedLiteral(data, ref pos, end, out literalEnd);
                MatchWhitespace(data, ref pos, end);
                ParseMethods.MatchUntilChar(';', true, data, ref pos, end);
                break;

            default:
                quotChar   = (char)0;
                literalPos = --pos;
                ParseMethods.MatchUntilChar(';', true, data, ref pos, end);
                literalEnd = Math.Max(literalPos, pos - 1);
                TrimWhitespace(data, ref literalPos, ref literalEnd);
                break;
            }
        }
        public StyleElement Next()
        {
            if (pos >= end)
            {
                return(null);
            }

            int start = pos;

            switch (data[pos++])
            {
            case '"':
            {
                int literalPos = pos;
                int literalEnd;
                ParseMethods.MatchDoubleQuotedLiteral(data, ref pos, end, out literalEnd);
                return(new StyleLiteral(data, start, pos - start, literalPos, literalEnd - literalPos, '"'));
            }

            case '\'':
            {
                int literalPos = pos;
                int literalEnd;
                ParseMethods.MatchSingleQuotedLiteral(data, ref pos, end, out literalEnd);
                return(new StyleLiteral(data, start, pos - start, literalPos, literalEnd - literalPos, '\''));
            }

            case '/':
                if (ParseMethods.SubstringMatch(data, pos - 1, end, "//"))
                {
                    pos++;
                    ParseMethods.MatchSingleLineComment(data, ref pos, end);
                    return(new StyleComment(data, start, pos - start));
                }
                else if (ParseMethods.SubstringMatch(data, pos - 1, end, "/*"))
                {
                    pos++;
                    ParseMethods.MatchMultiLineComment(data, ref pos, end);
                    return(new StyleComment(data, start, pos - start));
                }
                goto default;

            case '<':
                if (ParseMethods.SubstringMatch(data, pos - 1, end, "<!--"))
                {
                    pos += 3;
                    ParseMethods.MatchSingleLineComment(data, ref pos, end);
                    return(new StyleComment(data, start, pos - start));
                }
                goto default;

            case '-':
                if (ParseMethods.SubstringMatch(data, pos - 1, end, "-->"))
                {
                    pos += 2;
                    ParseMethods.MatchSingleLineComment(data, ref pos, end);
                    return(new StyleComment(data, start, pos - start));
                }
                goto default;

            case 'u':
            case 'U':
            {
                if (ParseMethods.SubstringMatchIgnoreCase(data, pos - 1, end, "url("))
                {
                    int  literalPos;
                    int  literalEnd;
                    char quotChar;

                    pos += 3;
                    MatchUrl(data, ref pos, end, out literalPos, out literalEnd, out quotChar);
                    return(new StyleUrl(data, start, pos - start, literalPos, literalEnd - literalPos, quotChar));
                }
                goto default;
            }

            case '@':
            {
                const string IMPORT = "@import";
                if (ParseMethods.SubstringMatchIgnoreCase(data, pos - 1, end, IMPORT))
                {
                    // We play a little fast and loose with CSS here.  Technically
                    // it's possible for "@import" to be immediately followed by
                    // something besides a whitespace char and still be valid, but
                    // we will not recognize those cases as @import statements,
                    // except when the following char is a quote.
                    int nextCharIndex = pos - 1 + IMPORT.Length;
                    if (data.Length > nextCharIndex)
                    {
                        char nextChar = data[nextCharIndex];
                        if (IsWhitespace(nextChar))
                        {
                            pos += IMPORT.Length;
                        }
                        else if (nextChar == '\'' || nextChar == '"')
                        {
                            pos += IMPORT.Length - 1;
                        }
                        else
                        {
                            goto default;          // per note above, treat as normal text
                        }
                        int  literalPos;
                        int  literalEnd;
                        char quotChar;

                        MatchImport(data, ref pos, end, out literalPos, out literalEnd, out quotChar);
                        return(new StyleImport(data, start, pos - start, literalPos, literalEnd - literalPos, quotChar));
                    }
                }
                goto default;
            }

            default:
                MatchNormal(data, ref pos, end);
                return(new StyleText(data, start, pos - start));
            }
        }