//
        // Helper routine for parsing a code entity from a token stream.
        //
        // This terminology is mostly legacy from an older implementation of Epoch.
        // An entity is really just a branch/flow-control construct such as a loop
        // or an if/else statement. Typically there is an expression which controls
        // execution and an associated code block.
        //
        internal static bool ParseEntity(ParseSession parser, LexicalScope parentscope, int starttoken, out int consumedtokens)
        {
            consumedtokens = starttoken;
            int totaltokens = starttoken;

            if (parser.CheckToken(totaltokens, "if"))
            {
                if (!parser.CheckToken(totaltokens + 1, "("))
                {
                    return(false);
                }

                totaltokens += 2;

                var expr = Expression.Parse(parser, totaltokens, out totaltokens);
                if (expr == null)
                {
                    throw new SyntaxError("if() statement must be supplied with a valid Boolean-typed expression", parser.ReversePeekToken());
                }

                while (parser.CheckToken(totaltokens, ")"))
                {
                    ++totaltokens;
                }

                if (!parser.CheckToken(totaltokens, "{"))
                {
                    throw new SyntaxError("if() statement must be followed by a code block surrounded in braces { }", parser.PeekToken(totaltokens));
                }

                ++totaltokens;
                LexicalScope.Parse(parser, parentscope, totaltokens, out totaltokens);

                while (parser.CheckToken(totaltokens, "elseif"))
                {
                    totaltokens += 2;
                    var condexpr = Expression.Parse(parser, totaltokens, out totaltokens);
                    if (condexpr == null)
                    {
                        throw new SyntaxError("elseif() statement must be supplied with a valid Boolean-typed expression", parser.ReversePeekToken());
                    }

                    while (parser.CheckToken(totaltokens, ")"))
                    {
                        ++totaltokens;
                    }

                    if (!parser.CheckToken(totaltokens, "{"))
                    {
                        throw new SyntaxError("elseif() statement must be followed by a code block surrounded in braces { }", parser.PeekToken(totaltokens));
                    }

                    ++totaltokens;
                    LexicalScope.Parse(parser, parentscope, totaltokens, out totaltokens);
                }

                if (parser.CheckToken(totaltokens, "else"))
                {
                    ++totaltokens;
                    if (!parser.CheckToken(totaltokens, "{"))
                    {
                        throw new SyntaxError("else statement must be followed by a code block surrounded in braces { }", parser.PeekToken(totaltokens));
                    }

                    ++totaltokens;
                    LexicalScope.Parse(parser, parentscope, totaltokens, out totaltokens);
                }

                consumedtokens = totaltokens;
                return(true);
            }
            else if (parser.CheckToken(totaltokens, "while"))
            {
                if (!parser.CheckToken(totaltokens + 1, "("))
                {
                    throw new SyntaxError("while() statement must be supplied with a valid Boolean-typed expression", parser.ReversePeekToken());
                }

                totaltokens += 2;

                while (parser.CheckToken(totaltokens, ")"))
                {
                    ++totaltokens;
                }

                var expr = Expression.Parse(parser, totaltokens, out totaltokens);
                ++totaltokens;

                if (!parser.CheckToken(totaltokens, "{"))
                {
                    throw new SyntaxError("while() statement must be followed by a code block surrounded in braces { }", parser.PeekToken(totaltokens));
                }

                ++totaltokens;
                LexicalScope.Parse(parser, parentscope, totaltokens, out totaltokens);

                consumedtokens = totaltokens;
                return(true);
            }

            return(false);
        }