void ParseTopLevel(BibTexLexerCallback callback)
        {
            while (c < MAX_C)
            {
                if ('@' != bibtex[c])
                {
                    ++c;
                }
                else
                {
                    // Get this entry
                    ParseEntry(callback);

                    // Skip spaces between entries
                    ParseWhiteSpace();
                }
            }

            callback.RaiseFinished();
        }
        private void ParseTopLevel(BibTexLexerCallback callback)
        {
            int prev_c = c;

            while (c < MAX_C)
            {
                // The `@keyword` must always be preceded by at least one whitespace
                // character so as to differentiate it from email addresses, etc.:
                // `joe@article` vs. ` @article`
                if ('@' != bibtex[c] || !Char.IsWhiteSpace(bibtex[c - 1]))
                {
                    ++c;
                }
                else
                {
                    // Hit a `@` BibTeX command start marker.

                    // Everything that we looped through thus far is either whitespace or comment or both:
                    string comment = bibtex.Substring(prev_c, c - prev_c).Trim();
                    if (!String.IsNullOrEmpty(comment))
                    {
                        callback.RaiseComment(comment);
                    }

                    // Get this @entry
                    ParseEntry(callback);

                    // Skip spaces between entries
                    ParseWhiteSpace();

                    prev_c = c;
                }
            }

            callback.RaiseFinished();
        }