/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

options
{
    STATIC = false;
    UNICODE_INPUT = true;
    // DEBUG_TOKEN_MANAGER = true;
    // DEBUG_PARSER = true;
}

PARSER_BEGIN(FMParser)

package freemarker.core;

import freemarker.core.LocalLambdaExpression.LambdaParameterList;
import freemarker.template.*;
import freemarker.template.utility.*;
import java.io.*;
import java.util.*;
import static freemarker.template.Configuration.*;

/**
 * This class is generated by JavaCC from a grammar file.
 */
public class FMParser {

    private static final int ITERATOR_BLOCK_KIND_LIST = 0; 
    private static final int ITERATOR_BLOCK_KIND_FOREACH = 1; 
    private static final int ITERATOR_BLOCK_KIND_ITEMS = 2; 
    private static final int ITERATOR_BLOCK_KIND_USER_DIRECTIVE = 3; 

    private static class ParserIteratorBlockContext {
        /**
         * loopVarName in <#list ... as loopVarName> or <#items as loopVarName>; null after we left the nested
         * block of #list or #items, respectively.
         */
        private String loopVarName;
        
        /**
         * loopVar1Name in <#list ... as k, loopVar2Name> or <#items as k, loopVar2Name>; null after we left the nested
         * block of #list or #items, respectively.
         */
        private String loopVar2Name;
        
        /**
         * See the ITERATOR_BLOCK_KIND_... costants.
         */
        private int kind;
        
        /**
         * Is this a key-value pair listing? When there's a nested #items, it's only set there. 
         */
        private boolean hashListing;
    }

    private Template template;

    private boolean stripWhitespace, stripText, preventStrippings;
    private int incompatibleImprovements;
    private OutputFormat outputFormat;
    private int autoEscapingPolicy;
    private boolean autoEscaping;
    private ParserConfiguration pCfg;

    /** Keeps track of #list and #foreach nesting. */
    private List<ParserIteratorBlockContext> iteratorBlockContexts;
    
    /**
     * Keeps track of the nesting depth of directives that support #break.
     */
    private int breakableDirectiveNesting;
    
    /**
     * Keeps track of the nesting depth of directives that support #continue.
     */
    private int continuableDirectiveNesting;
    
    private boolean inMacro, inFunction, requireArgsSpecialVariable;
    private LinkedList escapes = new LinkedList();
    private int mixedContentNesting; // for stripText

    /**
     * Create an FM expression parser using a string.
     *
     * @Deprecated This is an internal API of FreeMarker; can be removed any time.
     */
    static public FMParser createExpressionParser(String s) {
        SimpleCharStream scs = new SimpleCharStream(new StringReader(s), 1, 1, s.length());
        FMParserTokenManager token_source = new FMParserTokenManager(scs);
        token_source.SwitchTo(FMParserConstants.FM_EXPRESSION);
        FMParser parser = new FMParser(token_source);
        token_source.setParser(parser);
        return parser;
    }

    /**
     * Constructs a new parser object.
     * 
     * @param template
     *            The template associated with this parser.
     * @param reader
     *            The character stream to use as input
     * @param strictSyntaxMode
     *            Whether FreeMarker directives must start with a #
     *
     * @Deprecated This is an internal API of FreeMarker; will be removed in 2.4.
     */
    public FMParser(Template template, Reader reader, boolean strictSyntaxMode, boolean stripWhitespace) {
        this(template, reader, strictSyntaxMode, stripWhitespace, Configuration.AUTO_DETECT_TAG_SYNTAX);
    }

    /**
     * @Deprecated This is an internal API of FreeMarker; will be changed in 2.4.
     */
    public FMParser(Template template, Reader reader, boolean strictSyntaxMode, boolean stripWhitespace, int tagSyntax) {
        this(template, reader, strictSyntaxMode, stripWhitespace, tagSyntax,
                Configuration.PARSED_DEFAULT_INCOMPATIBLE_ENHANCEMENTS);
    }

    /**
     * @Deprecated This is an internal API of FreeMarker; will be changed in 2.4.
     */
    public FMParser(Template template, Reader reader, boolean strictSyntaxMode, boolean stripWhitespace,
            int tagSyntax, int incompatibleImprovements) {
        this(template, reader, strictSyntaxMode, stripWhitespace,
                tagSyntax, Configuration.AUTO_DETECT_NAMING_CONVENTION, incompatibleImprovements);
    }

    /**
     * @Deprecated This is an internal API of FreeMarker; will be changed in 2.4.
     */
    public FMParser(String template) {
        this(dummyTemplate(),
                new StringReader(template), true, true);
    }

    private static Template dummyTemplate() {
        try {
            return new Template(null, new StringReader(""), Configuration.getDefaultConfiguration());
        } catch (IOException e) {
            throw new RuntimeException("Failed to create dummy template", e);
        }
    }

    /**
     * @Deprecated This is an internal API of FreeMarker; will be changed in 2.4.
     */
    public FMParser(Template template, Reader reader, boolean strictSyntaxMode, boolean whitespaceStripping,
            int tagSyntax, int namingConvention, int incompatibleImprovements) {
        this(template, reader,
                new LegacyConstructorParserConfiguration(
                        strictSyntaxMode, whitespaceStripping,
                        tagSyntax, LEGACY_INTERPOLATION_SYNTAX, namingConvention,
                        template != null ? template.getParserConfiguration().getAutoEscapingPolicy()
                                : Configuration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY,
                        template != null ? template.getParserConfiguration().getOutputFormat()
                                : null,
                        template != null ? template.getParserConfiguration().getRecognizeStandardFileExtensions()
                                : null,
                        template != null ? template.getParserConfiguration().getTabSize()
                                : null,
                        new Version(incompatibleImprovements),
                        template != null ? template.getArithmeticEngine() : null));
    }

    /**
     * @Deprecated This is an internal API of FreeMarker; don't call it from outside FreeMarker.
     * 
     * @since 2.3.24
     */
    public FMParser(Template template, Reader reader, ParserConfiguration pCfg) {
        this(template, true, readerToTokenManager(reader, pCfg), pCfg);
    }

    private static FMParserTokenManager readerToTokenManager(Reader reader, ParserConfiguration pCfg) {
        SimpleCharStream simpleCharStream = new SimpleCharStream(reader, 1, 1);
        simpleCharStream.setTabSize(pCfg.getTabSize());
        return new FMParserTokenManager(simpleCharStream);
    }

    /**
     * @Deprecated This is an internal API of FreeMarker; don't call it from outside FreeMarker.
     * 
     * @since 2.3.24
     */
    public FMParser(Template template, boolean newTemplate, FMParserTokenManager tkMan, ParserConfiguration pCfg) {
        this(tkMan);

        NullArgumentException.check(pCfg);
        this.pCfg = pCfg;

        NullArgumentException.check(template);
        this.template = template;

        // Hack due to legacy public constructors (removed in 2.4):
        if (pCfg instanceof LegacyConstructorParserConfiguration) {
            LegacyConstructorParserConfiguration lpCfg = (LegacyConstructorParserConfiguration) pCfg;
            lpCfg.setArithmeticEngineIfNotSet(template.getArithmeticEngine());
            lpCfg.setAutoEscapingPolicyIfNotSet(template.getConfiguration().getAutoEscapingPolicy());
            lpCfg.setOutputFormatIfNotSet(template.getOutputFormat());
            lpCfg.setRecognizeStandardFileExtensionsIfNotSet(
                    template.getParserConfiguration().getRecognizeStandardFileExtensions());
            lpCfg.setTabSizeIfNotSet(
                    template.getParserConfiguration().getTabSize());
        }

        int incompatibleImprovements = pCfg.getIncompatibleImprovements().intValue();
        token_source.incompatibleImprovements = incompatibleImprovements;
        this.incompatibleImprovements = incompatibleImprovements;

        {
            OutputFormat outputFormatFromExt;
            if (!pCfg.getRecognizeStandardFileExtensions()
                    || (outputFormatFromExt = getFormatFromStdFileExt()) == null) {
                autoEscapingPolicy = pCfg.getAutoEscapingPolicy();
                outputFormat = pCfg.getOutputFormat();
            } else {
                // Override it
                autoEscapingPolicy = Configuration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY;
                outputFormat = outputFormatFromExt;
            }
        }
        recalculateAutoEscapingField();

        token_source.setParser(this);

        token_source.strictSyntaxMode = pCfg.getStrictSyntaxMode();

        int tagSyntax = pCfg.getTagSyntax();
        switch (tagSyntax) {
        case Configuration.AUTO_DETECT_TAG_SYNTAX:
            token_source.autodetectTagSyntax = true;
            break;
        case Configuration.ANGLE_BRACKET_TAG_SYNTAX:
            token_source.squBracTagSyntax = false;
            break;
        case Configuration.SQUARE_BRACKET_TAG_SYNTAX:
            token_source.squBracTagSyntax = true;
            break;
        default:
            throw new IllegalArgumentException("Illegal argument for tagSyntax: " + tagSyntax);
        }

        token_source.interpolationSyntax = pCfg.getInterpolationSyntax();

        int namingConvention = pCfg.getNamingConvention();
        switch (namingConvention) {
        case Configuration.AUTO_DETECT_NAMING_CONVENTION:
        case Configuration.CAMEL_CASE_NAMING_CONVENTION:
        case Configuration.LEGACY_NAMING_CONVENTION:
            token_source.initialNamingConvention = namingConvention;
            token_source.namingConvention = namingConvention;
            break;
        default:
            throw new IllegalArgumentException("Illegal argument for namingConvention: " + namingConvention);
        }

        this.stripWhitespace = pCfg.getWhitespaceStripping();

        // If this is a Template under construction, we do the below.
        // If this is just the enclosing Template for ?eval or such, we must not modify it.
        if (newTemplate) {
            _TemplateAPI.setAutoEscaping(template, autoEscaping);
            _TemplateAPI.setOutputFormat(template, outputFormat);
        }
    }

    void setupStringLiteralMode(FMParser parentParser, OutputFormat outputFormat) {
        FMParserTokenManager parentTokenSource = parentParser.token_source;

        token_source.initialNamingConvention = parentTokenSource.initialNamingConvention;
        token_source.namingConvention = parentTokenSource.namingConvention;
        token_source.namingConventionEstabilisher = parentTokenSource.namingConventionEstabilisher;
        token_source.SwitchTo(NO_DIRECTIVE);

        this.outputFormat = outputFormat;
        recalculateAutoEscapingField();
        if (incompatibleImprovements < _VersionInts.V_2_3_24) {
            // Emulate bug, where the string literal parser haven't inherited the IcI:
            incompatibleImprovements = _VersionInts.V_2_3_0;
        }

        // So that loop variable built-ins, like ?index, works inside the interpolations in the string literal:
        iteratorBlockContexts = parentParser.iteratorBlockContexts;
    }

    void tearDownStringLiteralMode(FMParser parentParser) {
        // If the naming convention was established inside the string literal, it's inherited by the parent:
        FMParserTokenManager parentTokenSource = parentParser.token_source;
        parentTokenSource.namingConvention = token_source.namingConvention;
        parentTokenSource.namingConventionEstabilisher = token_source.namingConventionEstabilisher;
    }

    /**
     * Used when we need to recreate the source code from the AST (such as for the FM2 to FM3 converter).
     */
    void setPreventStrippings(boolean preventStrippings) {
        this.preventStrippings = preventStrippings;
    }

    private OutputFormat getFormatFromStdFileExt() {
        String sourceName = template.getSourceName();
        if (sourceName == null) {
            return null; // Not possible anyway...
        }

        int ln = sourceName.length();
        if (ln < 5) return null;

        char c = sourceName.charAt(ln - 5);
        if (c != '.') return null;

        c = sourceName.charAt(ln - 4);
        if (c != 'f' && c != 'F') return null;

        c = sourceName.charAt(ln - 3);
        if (c != 't' && c != 'T') return null;

        c = sourceName.charAt(ln - 2);
        if (c != 'l' && c != 'L') return null;

        c = sourceName.charAt(ln - 1);
        try {
            // Note: We get the output formats by name, so that custom overrides take effect.
            if (c == 'h' || c == 'H') {
                return template.getConfiguration().getOutputFormat(HTMLOutputFormat.INSTANCE.getName());
                }
            if (c == 'x' || c == 'X') {
                return template.getConfiguration().getOutputFormat(XMLOutputFormat.INSTANCE.getName());
            }
        } catch (UnregisteredOutputFormatException e) {
            throw new BugException("Unregistered std format", e);
        }
        return null;
    }

    /**
     * Updates the {@link #autoEscaping} field based on the {@link #autoEscapingPolicy} and {@link #outputFormat} fields.
     */
    private void recalculateAutoEscapingField() {
        if (outputFormat instanceof MarkupOutputFormat) {
            if (autoEscapingPolicy == Configuration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY) {
                autoEscaping = ((MarkupOutputFormat) outputFormat).isAutoEscapedByDefault();
            } else if (autoEscapingPolicy == Configuration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY
	        || autoEscapingPolicy == Configuration.FORCE_AUTO_ESCAPING_POLICY) {
                autoEscaping = true;
            } else if (autoEscapingPolicy == Configuration.DISABLE_AUTO_ESCAPING_POLICY) {
                autoEscaping = false;
            } else {
                throw new IllegalStateException("Unhandled autoEscaping enum: " + autoEscapingPolicy);
            }
        } else {
            autoEscaping = false;
        }
    }

    MarkupOutputFormat getMarkupOutputFormat() {
        return outputFormat instanceof MarkupOutputFormat ? (MarkupOutputFormat) outputFormat : null;
    }

    /**
     * Don't use it, unless you are developing FreeMarker itself.
     */
    public int _getLastTagSyntax() {
        return token_source.squBracTagSyntax
                ? Configuration.SQUARE_BRACKET_TAG_SYNTAX
                : Configuration.ANGLE_BRACKET_TAG_SYNTAX;
    }

    /**
     * Don't use it, unless you are developing FreeMarker itself.
     * The naming convention used by this template; if it couldn't be detected so far, it will be the most probable one.
     * This could be used for formatting error messages, but not for anything serious.
     */
    public int _getLastNamingConvention() {
        return token_source.namingConvention;
    }

    /**
     * Throw an exception if the expression passed in is a String Literal
     */
    private void notStringLiteral(Expression exp, String expected) throws ParseException {
        if (exp instanceof StringLiteral) {
            throw new ParseException(
                    "Found string literal: " + exp + ". Expecting: " + expected,
                    exp);
        }
    }

    /**
     * Throw an exception if the expression passed in is a Number Literal
     */
    private void notNumberLiteral(Expression exp, String expected) throws ParseException {
        if (exp instanceof NumberLiteral) {
            throw new ParseException(
                    "Found number literal: " + exp.getCanonicalForm() + ". Expecting " + expected,
                    exp);
        }
    }

    /**
     * Throw an exception if the expression passed in is a boolean Literal
     */
    private void notBooleanLiteral(Expression exp, String expected) throws ParseException {
        if (exp instanceof BooleanLiteral) {
            throw new ParseException("Found: " + exp.getCanonicalForm() + " literal. Expecting " + expected , exp);
        }
    }

    /**
     * Throw an exception if the expression passed in is a Hash Literal
     */
    private void notHashLiteral(Expression exp, String expected) throws ParseException {
        if (exp instanceof HashLiteral) {
            throw new ParseException(
                    "Found hash literal: " + exp.getCanonicalForm() + ". Expecting " + expected,
                    exp);
        }
    }

    /**
     * Throw an exception if the expression passed in is a List Literal
     */
    private void notListLiteral(Expression exp, String expected)
            throws ParseException
    {
        if (exp instanceof ListLiteral) {
            throw new ParseException(
                    "Found list literal: " + exp.getCanonicalForm() + ". Expecting " + expected,
                    exp);
        }
    }

    /**
     * Throw an exception if the expression passed in is a literal other than of the numerical type
     */
    private void numberLiteralOnly(Expression exp) throws ParseException {
        notStringLiteral(exp, "number");
        notListLiteral(exp, "number");
        notHashLiteral(exp, "number");
        notBooleanLiteral(exp, "number");
    }

    /**
     * Throw an exception if the expression passed in is not a string.
     */
    private void stringLiteralOnly(Expression exp) throws ParseException {
        notNumberLiteral(exp, "string");
        notListLiteral(exp, "string");
        notHashLiteral(exp, "string");
        notBooleanLiteral(exp, "string");
    }

    /**
     * Throw an exception if the expression passed in is a literal other than of the boolean type
     */
    private void booleanLiteralOnly(Expression exp) throws ParseException {
        notStringLiteral(exp, "boolean (true/false)");
        notListLiteral(exp, "boolean (true/false)");
        notHashLiteral(exp, "boolean (true/false)");
        notNumberLiteral(exp, "boolean (true/false)");
    }

    private Expression escapedExpression(Expression exp) throws ParseException {
        if (!escapes.isEmpty()) {
            return ((EscapeBlock) escapes.getFirst()).doEscape(exp);
        } else {
            return exp;
        }
    }

    private boolean getBoolean(Expression exp, boolean legacyCompat) throws ParseException {
        TemplateModel tm = null;
        try {
            tm = exp.eval(null);
        } catch (Exception e) {
            throw new ParseException(e.getMessage()
                    + "\nCould not evaluate expression: "
                    + exp.getCanonicalForm(),
                    exp,
                    e);
        }
        if (tm instanceof TemplateBooleanModel) {
            try {
                return ((TemplateBooleanModel) tm).getAsBoolean();
            } catch (TemplateModelException tme) {
            }
        }
        if (legacyCompat && tm instanceof TemplateScalarModel) {
            try {
                return StringUtil.getYesNo(((TemplateScalarModel) tm).getAsString());
            } catch (Exception e) {
                throw new ParseException(e.getMessage()
                        + "\nExpecting boolean (true/false), found: " + exp.getCanonicalForm(),
                        exp);
            }
        }
        throw new ParseException("Expecting boolean (true/false) parameter", exp);
    }

    void checkCurrentOutputFormatCanEscape(Token start) throws ParseException {
        if (!(outputFormat instanceof MarkupOutputFormat)) {
            throw new ParseException("The current output format can't do escaping: " + outputFormat,
                    template, start);
        }
    }

    private static String forcedAutoEscapingPolicyExceptionMessage(OutputFormat outputFormat) {
        return forcedAutoEscapingPolicyExceptionMessage("Non-markup output format " + outputFormat);
    }

    private static String forcedAutoEscapingPolicyExceptionMessage(String whatCanNotBeUsed) {
        return whatCanNotBeUsed + " can't be used when the \"" + Configuration.AUTO_ESCAPING_POLICY_KEY + "\" "
                + "configuration setting was set to \"force\" (FORCE_AUTO_ESCAPING_POLICY).";
    }

    private ParserIteratorBlockContext pushIteratorBlockContext() {
        if (iteratorBlockContexts == null) {
            iteratorBlockContexts = new ArrayList<ParserIteratorBlockContext>(4);
        }
        ParserIteratorBlockContext newCtx = new ParserIteratorBlockContext();
        iteratorBlockContexts.add(newCtx);
        return newCtx;
    }

    private void popIteratorBlockContext() {
        iteratorBlockContexts.remove(iteratorBlockContexts.size() - 1);
    }

    private ParserIteratorBlockContext peekIteratorBlockContext() {
        int size = iteratorBlockContexts != null ? iteratorBlockContexts.size() : 0;
        return size != 0 ? (ParserIteratorBlockContext) iteratorBlockContexts.get(size - 1) : null;
    }

    private void checkLoopVariableBuiltInLHO(String loopVarName, Expression lhoExp, Token biName)
            throws ParseException {
        int size = iteratorBlockContexts != null ? iteratorBlockContexts.size() : 0;
        for (int i = size - 1; i >= 0; i--) {
            ParserIteratorBlockContext ctx = iteratorBlockContexts.get(i);
            if (loopVarName.equals(ctx.loopVarName) || loopVarName.equals(ctx.loopVar2Name)) {
                if (ctx.kind == ITERATOR_BLOCK_KIND_USER_DIRECTIVE) {
			        throw new ParseException(
			                "The left hand operand of ?" + biName.image
			                + " can't be the loop variable of an user defined directive: "
			                +  loopVarName,
			                lhoExp);
                }
                return;  // success
            }
        }
        throw new ParseException(
                "The left hand operand of ?" + biName.image + " must be a loop variable, "
                + "but there's no loop variable in scope with this name: " + loopVarName,
                lhoExp);
    }

	private String forEachDirectiveSymbol() {
	    // [2.4] Use camel case as the default
	    return token_source.namingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION ? "#forEach" : "#foreach";
	}

}

PARSER_END(FMParser)

/**
 * The lexer portion defines 5 lexical states:
 * DEFAULT, FM_EXPRESSION, IN_PAREN, NO_PARSE, and EXPRESSION_COMMENT.
 * The DEFAULT state is when you are parsing
 * text but are not inside a FreeMarker expression.
 * FM_EXPRESSION is the state you are in
 * when the parser wants a FreeMarker expression.
 * IN_PAREN is almost identical really. The difference
 * is that you are in this state when you are within
 * FreeMarker expression and also within (...).
 * This is a necessary subtlety because the
 * ">" and ">=" symbols can only be used
 * within parentheses because otherwise, it would
 * be ambiguous with the end of a directive.
 * So, for example, you enter the FM_EXPRESSION state
 * right after a ${ and leave it after the matching }.
 * Or, you enter the FM_EXPRESSION state right after
 * an "<if" and then, when you hit the matching ">"
 * that ends the if directive,
 * you go back to DEFAULT lexical state.
 * If, within the FM_EXPRESSION state, you enter a
 * parenthetical expression, you enter the IN_PAREN
 * state.
 * Note that whitespace is ignored in the
 * FM_EXPRESSION and IN_PAREN states
 * but is passed through to the parser as PCDATA in the DEFAULT state.
 * NO_PARSE and EXPRESSION_COMMENT are extremely simple
 * lexical states. NO_PARSE is when you are in a comment
 * block and EXPRESSION_COMMENT is when you are in a comment
 * that is within an FTL expression.
 */
TOKEN_MGR_DECLS:
{

    private static final String PLANNED_DIRECTIVE_HINT
            = "(If you have seen this directive in use elsewhere, this was a planned directive, "
                + "so maybe you need to upgrade FreeMarker.)";

    /**
     * The noparseTag is set when we enter a block of text that the parser more or less ignores. These are <noparse> and
     * <comment>. This variable tells us what the closing tag should be, and when we hit that, we resume parsing. Note
     * that with this scheme, <comment> and <noparse> tags cannot nest recursively, but it is not clear how important
     * that is.
     */
    String noparseTag;

    private FMParser parser;
    private int postInterpolationLexState = -1;
    /**
     * Keeps track of how deeply nested we have the hash literals. This is necessary since we need to be able to
     * distinguish the } used to close a hash literal and the one used to close a ${
     */
    private int curlyBracketNesting;
    private int parenthesisNesting;
    private int bracketNesting;
    private boolean inFTLHeader;
    boolean strictSyntaxMode,
            squBracTagSyntax,
            autodetectTagSyntax,
            tagSyntaxEstablished,
            inInvocation;
    int interpolationSyntax;
    int initialNamingConvention;
    int namingConvention;
    Token namingConventionEstabilisher;
    int incompatibleImprovements;

    void setParser(FMParser parser) {
        this.parser = parser;
    }

    // This method checks if we are in a strict mode where all
    // FreeMarker directives must start with <#. It also handles
    // tag syntax detection. If you update this logic, take a look
    // at the UNKNOWN_DIRECTIVE token too.
    private void handleTagSyntaxAndSwitch(Token tok, int tokenNamingConvention, int newLexState) {
        final String image = tok.image;
        
        // Non-strict syntax (deprecated) only supports legacy naming convention.
        // We didn't push this on the tokenizer because it made it slow, so we filter here.
        if (!strictSyntaxMode
                && (tokenNamingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION)
                && !isStrictTag(image)) {
            tok.kind = STATIC_TEXT_NON_WS;
            return;
        }
        
        char firstChar = image.charAt(0);
        if (autodetectTagSyntax && !tagSyntaxEstablished) {
            squBracTagSyntax = (firstChar == '[');
        }
        if ((firstChar == '[' && !squBracTagSyntax) || (firstChar == '<' && squBracTagSyntax)) {
            tok.kind = STATIC_TEXT_NON_WS;
            return;
        }
        
        if (!strictSyntaxMode) {
            // Legacy feature (or bug?): Tag syntax never gets estabilished in non-strict mode.
            // We do establish the naming convention though.
            checkNamingConvention(tok, tokenNamingConvention);
            SwitchTo(newLexState);
            return;
        }
        
        // For square bracket tags there's no non-strict token, so we are sure that it's an FTL tag.
        // But if it's an angle bracket tag, we have to check if it's just static text or and FTL tag, because the
        // tokenizer will emit the same kind of token for both.
        if (!squBracTagSyntax && !isStrictTag(image)) {
            tok.kind = STATIC_TEXT_NON_WS;
            return;
        }
        
        // We only get here if this is a strict FTL tag.
        tagSyntaxEstablished = true;
        
        if (incompatibleImprovements >= _VersionInts.V_2_3_28
                || interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX) {
	        // For END_xxx tags, as they can't contain expressions, the whole tag is a single token. So this is the only
	        // chance to check if we got something inconsistent like `</#if]`. (We can't do this at the #CLOSE_TAG1 or
	        // such, as at that point it's possible that the tag syntax is not yet established.)
	        char lastChar = image.charAt(image.length() - 1);
	        // Is it an end tag?
	        if (lastChar == ']' || lastChar == '>') {
	            if (!squBracTagSyntax && lastChar != '>' || squBracTagSyntax && lastChar != ']') {
		            throw new TokenMgrError(
		                    "The tag shouldn't end with \""+ lastChar + "\".",
		                    TokenMgrError.LEXICAL_ERROR,
		                    tok.beginLine, tok.beginColumn,
		                    tok.endLine, tok.endColumn);
                }
            } // if end-tag
        }

        checkNamingConvention(tok, tokenNamingConvention);

        SwitchTo(newLexState);
    }

    void checkNamingConvention(Token tok) {
        checkNamingConvention(tok, _CoreStringUtils.getIdentifierNamingConvention(tok.image));
    }

    void checkNamingConvention(Token tok, int tokenNamingConvention) {
        if (tokenNamingConvention != Configuration.AUTO_DETECT_NAMING_CONVENTION) {
	        if (namingConvention == Configuration.AUTO_DETECT_NAMING_CONVENTION) {
	            namingConvention = tokenNamingConvention;
	            namingConventionEstabilisher = tok;
	        } else if (namingConvention != tokenNamingConvention) {
                throw newNameConventionMismatchException(tok);
	        }
        }
    }

    private TokenMgrError newNameConventionMismatchException(Token tok) {
        return new TokenMgrError(
                "Naming convention mismatch. "
                + "Identifiers that are part of the template language (not the user specified ones) "
                + (initialNamingConvention == Configuration.AUTO_DETECT_NAMING_CONVENTION
                    ? "must consistently use the same naming convention within the same template. This template uses "
                    : "must use the configured naming convention, which is the ")
                + (namingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION
                            ? "camel case naming convention (like: exampleName) "
                            : (namingConvention == Configuration.LEGACY_NAMING_CONVENTION
                                    ? "legacy naming convention (directive (tag) names are like examplename, "
                                      + "everything else is like example_name) "
                                    : "??? (internal error)"
                                    ))
                + (namingConventionEstabilisher != null
                        ? "estabilished by auto-detection at "
                            + _MessageUtil.formatPosition(
                                    namingConventionEstabilisher.beginLine, namingConventionEstabilisher.beginColumn)
                            + " by token " + StringUtil.jQuote(namingConventionEstabilisher.image.trim())
                        : "")
                + ", but the problematic token, " + StringUtil.jQuote(tok.image.trim())
                + ", uses a different convention.",
                TokenMgrError.LEXICAL_ERROR,
                tok.beginLine, tok.beginColumn, tok.endLine, tok.endColumn);
    }

    /**
     * Used for tags whose name isn't affected by naming convention.
     */
    private void handleTagSyntaxAndSwitch(Token tok, int newLexState) {
        handleTagSyntaxAndSwitch(tok, Configuration.AUTO_DETECT_NAMING_CONVENTION, newLexState);
    }

    private boolean isStrictTag(String image) {
        return image.length() > 2 && (image.charAt(1) == '#' || image.charAt(2) == '#');
    }

    /**
     * Detects the naming convention used, both in start- and end-tag tokens.
     *
     * @param charIdxInName
     *         The index of the deciding character relatively to the first letter of the name.
     */
    private static int getTagNamingConvention(Token tok, int charIdxInName) {
        return _CoreStringUtils.isUpperUSASCII(getTagNameCharAt(tok, charIdxInName))
                ? Configuration.CAMEL_CASE_NAMING_CONVENTION : Configuration.LEGACY_NAMING_CONVENTION;
    }

    static char getTagNameCharAt(Token tok, int charIdxInName) {
        final String image = tok.image;

        // Skip tag delimiter:
        int idx = 0;
        for (;;) {
            final char c = image.charAt(idx);
            if (c != '<' && c != '[' && c != '/' && c != '#') {
                break;
            }
            idx++;
        }

        return image.charAt(idx + charIdxInName);
    }

    private void unifiedCall(Token tok) {
        char firstChar = tok.image.charAt(0);
        if (autodetectTagSyntax && !tagSyntaxEstablished) {
            squBracTagSyntax = (firstChar == '[');
        }
        if (squBracTagSyntax && firstChar == '<') {
            tok.kind = STATIC_TEXT_NON_WS;
            return;
        }
        if (!squBracTagSyntax && firstChar == '[') {
            tok.kind = STATIC_TEXT_NON_WS;
            return;
        }
        tagSyntaxEstablished = true;
        SwitchTo(NO_SPACE_EXPRESSION);
    }

    private void unifiedCallEnd(Token tok) {
        char firstChar = tok.image.charAt(0);
        if (squBracTagSyntax && firstChar == '<') {
            tok.kind = STATIC_TEXT_NON_WS;
            return;
        }
        if (!squBracTagSyntax && firstChar == '[') {
            tok.kind = STATIC_TEXT_NON_WS;
            return;
        }
    }

    private void startInterpolation(Token tok) {
        if (
                interpolationSyntax == LEGACY_INTERPOLATION_SYNTAX
                    && tok.kind == SQUARE_BRACKET_INTERPOLATION_OPENING
                || interpolationSyntax == DOLLAR_INTERPOLATION_SYNTAX
                    && tok.kind != DOLLAR_INTERPOLATION_OPENING
                || interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX
                    && tok.kind != SQUARE_BRACKET_INTERPOLATION_OPENING) {
            tok.kind = STATIC_TEXT_NON_WS;
            return;
        }

        if (postInterpolationLexState != -1) {
            // This certainly never occurs, as starting an interpolation in expression mode fails earlier.
            char c = tok.image.charAt(0);
            throw new TokenMgrError(
                    "You can't start an interpolation (" + tok.image + "..."
                    + (interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX ? "]" : "}")
                    + ") here as you are inside another interpolation.)",
                    TokenMgrError.LEXICAL_ERROR,
                    tok.beginLine, tok.beginColumn,
                    tok.endLine, tok.endColumn);
        }
        postInterpolationLexState = curLexState;
        SwitchTo(FM_EXPRESSION);
    }

    private void endInterpolation(Token closingTk) {
        SwitchTo(postInterpolationLexState);
        postInterpolationLexState = -1;
    }

    private TokenMgrError newUnexpectedClosingTokenException(Token closingTk) {
            return new TokenMgrError(
                    "You can't have an \"" + closingTk.image + "\" here, as there's nothing open that it could close.",
                    TokenMgrError.LEXICAL_ERROR,
                    closingTk.beginLine, closingTk.beginColumn,
                    closingTk.endLine, closingTk.endColumn);
    }

    private void eatNewline() {
        int charsRead = 0;
        try {
            while (true) {
                char c = input_stream.readChar();
                ++charsRead;
                if (!Character.isWhitespace(c)) {
                    input_stream.backup(charsRead);
                    return;
                } else if (c == '\r') {
                    char next = input_stream.readChar();
                    ++charsRead;
                    if (next != '\n') {
                        input_stream.backup(1);
                    }
                    return;
                } else if (c == '\n') {
                    return;
                }
            }
        } catch (IOException ioe) {
            input_stream.backup(charsRead);
        }
    }

    private void ftlHeader(Token matchedToken) {
        if (!tagSyntaxEstablished) {
            squBracTagSyntax = matchedToken.image.charAt(0) == '[';
            tagSyntaxEstablished = true;
            autodetectTagSyntax = false;
        }
        String img = matchedToken.image;
        char firstChar = img.charAt(0);
        char lastChar = img.charAt(img.length() - 1);
        if ((firstChar == '[' && !squBracTagSyntax) || (firstChar == '<' && squBracTagSyntax)) {
            matchedToken.kind = STATIC_TEXT_NON_WS;
        }
        if (matchedToken.kind != STATIC_TEXT_NON_WS) {
            if (lastChar != '>' && lastChar != ']') {
                SwitchTo(FM_EXPRESSION);
                inFTLHeader = true;
            } else {
                eatNewline();
            }
        }
    }
}

TOKEN:
{
    <#BLANK : " " | "\t" | "\n" | "\r">
    |
    <#START_TAG : "<" | "<#" | "[#">
    |
    <#END_TAG : "</" | "</#" | "[/#">
    |
    <#CLOSE_TAG1 : (<BLANK>)* (">" | "]")>
    |
    <#CLOSE_TAG2 : (<BLANK>)* ("/")? (">" | "]")>
    |
    /*
     * ATTENTION: Update _CoreAPI.*_BUILT_IN_DIRECTIVE_NAMES if you add new directives!
     */
    <ATTEMPT : <START_TAG> "attempt" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <RECOVER : <START_TAG> "recover" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <IF : <START_TAG> "if" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <ELSE_IF : <START_TAG> "else" ("i" | "I") "f" <BLANK>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 4), FM_EXPRESSION);
    }
    |
    <LIST : <START_TAG> "list" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <ITEMS : <START_TAG> "items" (<BLANK>)+ <AS> <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <SEP : <START_TAG> "sep" <CLOSE_TAG1>>
    |
    <FOREACH : <START_TAG> "for" ("e" | "E") "ach" <BLANK>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 3), FM_EXPRESSION);
    }
    |
    <SWITCH : <START_TAG> "switch" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <CASE : <START_TAG> "case" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <ASSIGN : <START_TAG> "assign" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <GLOBALASSIGN : <START_TAG> "global" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <LOCALASSIGN : <START_TAG> "local" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <_INCLUDE : <START_TAG> "include" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <IMPORT : <START_TAG> "import" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <FUNCTION : <START_TAG> "function" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <MACRO : <START_TAG> "macro" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <TRANSFORM : <START_TAG> "transform" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <VISIT : <START_TAG> "visit" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <STOP : <START_TAG> "stop" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <RETURN : <START_TAG> "return" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <CALL : <START_TAG> "call" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <SETTING : <START_TAG> "setting" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <OUTPUTFORMAT : <START_TAG> "output" ("f"|"F") "ormat" <BLANK>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 6), FM_EXPRESSION);
    }
    |
    <AUTOESC : <START_TAG> "auto" ("e"|"E") "sc" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 4), DEFAULT);
    }
    |
    <NOAUTOESC : <START_TAG> "no" ("autoe"|"AutoE") "sc" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
    }
    |
    <COMPRESS : <START_TAG> "compress" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <COMMENT : <START_TAG> "comment" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, NO_PARSE); noparseTag = "comment";
    }
    |
    <TERSE_COMMENT : ("<" | "[") "#--" > { noparseTag = "-->"; handleTagSyntaxAndSwitch(matchedToken, NO_PARSE); }
    |
    <NOPARSE: <START_TAG> "no" ("p" | "P") "arse" <CLOSE_TAG1>> {
        int tagNamingConvention = getTagNamingConvention(matchedToken, 2);
        handleTagSyntaxAndSwitch(matchedToken, tagNamingConvention, NO_PARSE);
        noparseTag = tagNamingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION ? "noParse" : "noparse";
    }
    |
    <END_IF : <END_TAG> "if" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_LIST : <END_TAG> "list" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_ITEMS : <END_TAG> "items" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_SEP : <END_TAG> "sep" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_RECOVER : <END_TAG> "recover" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_ATTEMPT : <END_TAG> "attempt" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_FOREACH : <END_TAG> "for" ("e" | "E") "ach" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 3), DEFAULT);
    }
    |
    <END_LOCAL : <END_TAG> "local" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_GLOBAL : <END_TAG> "global" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_ASSIGN : <END_TAG> "assign" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_FUNCTION : <END_TAG> "function" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_MACRO : <END_TAG> "macro" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_OUTPUTFORMAT : <END_TAG> "output" ("f" | "F") "ormat" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 6), DEFAULT);
    }
    |
    <END_AUTOESC : <END_TAG> "auto" ("e" | "E") "sc" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 4), DEFAULT);
    }
    |
    <END_NOAUTOESC : <END_TAG> "no" ("autoe"|"AutoE") "sc" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
    }
    |
    <END_COMPRESS : <END_TAG> "compress" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_TRANSFORM : <END_TAG> "transform" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <END_SWITCH : <END_TAG> "switch" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <ELSE : <START_TAG> "else" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <BREAK : <START_TAG> "break" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <CONTINUE : <START_TAG> "continue" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <SIMPLE_RETURN : <START_TAG> "return" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <HALT : <START_TAG> "stop" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <FLUSH : <START_TAG> "flush" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <TRIM : <START_TAG> "t" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <LTRIM : <START_TAG> "lt" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <RTRIM : <START_TAG> "rt" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <NOTRIM : <START_TAG> "nt" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <DEFAUL : <START_TAG> "default" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <SIMPLE_NESTED : <START_TAG> "nested" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <NESTED : <START_TAG> "nested" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <SIMPLE_RECURSE : <START_TAG> "recurse" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <RECURSE : <START_TAG> "recurse" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <FALLBACK : <START_TAG> "fallback" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <ESCAPE : <START_TAG> "escape" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
    |
    <END_ESCAPE : <END_TAG> "escape" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
    |
    <NOESCAPE : <START_TAG> "no" ("e" | "E") "scape" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
    }
    |
    <END_NOESCAPE : <END_TAG> "no" ("e" | "E") "scape" <CLOSE_TAG1>> {
        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
    }
    |
    <UNIFIED_CALL : "<@" | "[@" > { unifiedCall(matchedToken); }
    |
    <UNIFIED_CALL_END : ("<" | "[") "/@" ((<ID>) ("."<ID>)*)? <CLOSE_TAG1>> { unifiedCallEnd(matchedToken); }
    |
    <FTL_HEADER : ("<#ftl" | "[#ftl") <BLANK>> { ftlHeader(matchedToken); }
    |
    <TRIVIAL_FTL_HEADER : ("<#ftl" | "[#ftl") ("/")? (">" | "]")> { ftlHeader(matchedToken); }
    |
    /*
     * ATTENTION: Update _CoreAPI.*_BUILT_IN_DIRECTIVE_NAMES if you add new directives!
     */
    <UNKNOWN_DIRECTIVE : ("[#" | "[/#" | "<#" | "</#") (["a"-"z", "A"-"Z", "_"])+>
    {
        if (!tagSyntaxEstablished && incompatibleImprovements < _VersionInts.V_2_3_19) {
            matchedToken.kind = STATIC_TEXT_NON_WS;
        } else {
            char firstChar = matchedToken.image.charAt(0);

            if (!tagSyntaxEstablished && autodetectTagSyntax) {
                squBracTagSyntax = (firstChar == '[');
                tagSyntaxEstablished = true;
            }

            if (firstChar == '<' && squBracTagSyntax) {
                matchedToken.kind = STATIC_TEXT_NON_WS;
            } else if (firstChar == '[' && !squBracTagSyntax) {
                matchedToken.kind = STATIC_TEXT_NON_WS;
            } else if (strictSyntaxMode) {
                String dn = matchedToken.image;
                int index = dn.indexOf('#');
                dn = dn.substring(index + 1);

                // Until the tokenizer/parser is reworked, we have this quirk where something like <#list>
                // doesn't match any directive starter tokens, because that token requires whitespace after the
                // name as it should be followed by parameters. For now we work this around so we don't report
                // unknown directive:
                if (_CoreAPI.ALL_BUILT_IN_DIRECTIVE_NAMES.contains(dn)) {
                    throw new TokenMgrError(
                            "#" + dn + " is an existing directive, but the tag is malformed. "
                            + " (See FreeMarker Manual / Directive Reference.)",
                            TokenMgrError.LEXICAL_ERROR,
                            matchedToken.beginLine, matchedToken.beginColumn + 1,
                            matchedToken.endLine, matchedToken.endColumn);
                }

                String tip = null;
                if (dn.equals("set") || dn.equals("var")) {
                    tip = "Use #assign or #local or #global, depending on the intented scope "
                          + "(#assign is template-scope). " + PLANNED_DIRECTIVE_HINT;
                } else if (dn.equals("else_if") || dn.equals("elif")) {
                	tip = "Use #elseif.";
                } else if (dn.equals("no_escape")) {
                	tip = "Use #noescape instead.";
                } else if (dn.equals("method")) {
                	tip = "Use #function instead.";
                } else if (dn.equals("head") || dn.equals("template") || dn.equals("fm")) {
                	tip = "You may meant #ftl.";
                } else if (dn.equals("try") || dn.equals("atempt")) {
                	tip = "You may meant #attempt.";
                } else if (dn.equals("for") || dn.equals("each") || dn.equals("iterate") || dn.equals("iterator")) {
                    tip = "You may meant #list (http://freemarker.org/docs/ref_directive_list.html).";
                } else if (dn.equals("prefix")) {
                    tip = "You may meant #import. " + PLANNED_DIRECTIVE_HINT;
                } else if (dn.equals("item") || dn.equals("row") || dn.equals("rows")) {
                    tip = "You may meant #items.";
                } else if (dn.equals("separator") || dn.equals("separate") || dn.equals("separ")) {
                    tip = "You may meant #sep.";
                } else {
                    tip = "Help (latest version): http://freemarker.org/docs/ref_directive_alphaidx.html; "
                            + "you're using FreeMarker " + Configuration.getVersion() + ".";
                }
                throw new TokenMgrError(
                        "Unknown directive: #" + dn + (tip != null ? ". " + tip : ""),
                        TokenMgrError.LEXICAL_ERROR,
                        matchedToken.beginLine, matchedToken.beginColumn + 1,
                        matchedToken.endLine, matchedToken.endColumn);
            }
        }
    }
}

<DEFAULT, NO_DIRECTIVE> TOKEN :
{
    <STATIC_TEXT_WS : ("\n" | "\r" | "\t" | " ")+>
    |
    <STATIC_TEXT_NON_WS : (~["$", "<", "#", "[", "{", "\n", "\r", "\t", " "])+>
    |
    <STATIC_TEXT_FALSE_ALARM : "$" | "#" | "<" | "[" | "{"> // to handle a lone dollar sign or "<" or "# or <@ with whitespace after"
    |
    <DOLLAR_INTERPOLATION_OPENING : "${"> { startInterpolation(matchedToken); }
    |
    <HASH_INTERPOLATION_OPENING : "#{"> { startInterpolation(matchedToken); }
    |
    <SQUARE_BRACKET_INTERPOLATION_OPENING : "[="> { startInterpolation(matchedToken); }
}

<FM_EXPRESSION, IN_PAREN, NAMED_PARAMETER_EXPRESSION> SKIP :
{
    < ( " " | "\t" | "\n" | "\r" )+ >
    |
    < ("<" | "[") ("#" | "!") "--"> : EXPRESSION_COMMENT
}

<EXPRESSION_COMMENT> SKIP:
{
    < (~["-", ">", "]"])+ >
    |
    < ">">
    |
    < "]">
    |
    < "-">
    |
    < "-->" | "--]">
    {
        if (parenthesisNesting > 0) SwitchTo(IN_PAREN);
        else if (inInvocation) SwitchTo(NAMED_PARAMETER_EXPRESSION);
        else SwitchTo(FM_EXPRESSION);
    }
}

<FM_EXPRESSION, IN_PAREN, NO_SPACE_EXPRESSION, NAMED_PARAMETER_EXPRESSION> TOKEN :
{
    <#ESCAPED_CHAR :
        "\\"
        (
            ("n" | "t" | "r" | "f" | "b" | "g" | "l" | "a" | "\\" | "'" | "\"" | "{" | "=")
            |
            ("x" ["0"-"9", "A"-"F", "a"-"f"])
        )
    >
    |
    <STRING_LITERAL :
        (
            "\""
            ((~["\"", "\\"]) | <ESCAPED_CHAR>)*
            "\""
        )
        |
        (
            "'"
            ((~["'", "\\"]) | <ESCAPED_CHAR>)*
            "'"
        )
    >
    |
    <RAW_STRING : "r" (("\"" (~["\""])* "\"") | ("'" (~["'"])* "'"))>
    |
    <FALSE : "false">
    |
    <TRUE : "true">
    |
    <INTEGER : (["0"-"9"])+>
    |
    <DECIMAL : <INTEGER> "." <INTEGER>>
    |
    <DOT : ".">
    |
    <DOT_DOT : "..">
    |
    <DOT_DOT_LESS : "..<" | "..!" >
    |
    <DOT_DOT_ASTERISK : "..*" >
    |
    <BUILT_IN : "?">
    |
    <EXISTS : "??">
    |
    <EQUALS : "=">
    |
    <DOUBLE_EQUALS : "==">
    |
    <NOT_EQUALS : "!=">
    |
    <PLUS_EQUALS : "+=">
    |
    <MINUS_EQUALS : "-=">
    |
    <TIMES_EQUALS : "*=">
    |
    <DIV_EQUALS : "/=">
    |
    <MOD_EQUALS : "%=">
    |
    <PLUS_PLUS : "++">
    |
    <MINUS_MINUS : "--">
    |
    <LESS_THAN : "lt" | "\\lt" | "<" | "&lt;">
    |
    <LESS_THAN_EQUALS : "lte" | "\\lte" | "<=" | "&lt;=">
    |
    <ESCAPED_GT: "gt" | "\\gt" |  "&gt;">
    |
    <ESCAPED_GTE : "gte" | "\\gte" | "&gt;=">
    |
    <LAMBDA_ARROW : "->" | "-&gt;">
    |
    <PLUS : "+">
    |
    <MINUS : "-">
    |
    <TIMES : "*">
    |
    <DOUBLE_STAR : "**">
    |
    <ELLIPSIS : "...">
    |
    <DIVIDE : "/">
    |
    <PERCENT : "%">
    |
    <AND : "&" | "&&" | "&amp;&amp;" | "\\and" >
    |
    <OR : "|" | "||">
    |
    <EXCLAM : "!">
    |
    <COMMA : ",">
    |
    <SEMICOLON : ";">
    |
    <COLON : ":">
    |
    <OPEN_BRACKET : "[">
    {
        ++bracketNesting;
    }
    |
    <CLOSE_BRACKET : "]">
    {
        if (bracketNesting > 0) {
            --bracketNesting;
        } else if (interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX && postInterpolationLexState != -1) {
            endInterpolation(matchedToken);
        } else {
            // There's a legacy glitch where you can always close a tag with `]`, like `<#if x]`. We have to keep that
            // working for backward compatibility, hence we don't always throw at !squBracTagSyntax:
            if (!squBracTagSyntax
                    && (incompatibleImprovements >= _VersionInts.V_2_3_28
                            || interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX)
                    || postInterpolationLexState != -1 /* We're in an interpolation => We aren't in a tag */) {
                throw newUnexpectedClosingTokenException(matchedToken);
            }

            // Close tag, either legally or to emulate legacy glitch:
            matchedToken.kind = DIRECTIVE_END;
            if (inFTLHeader) {
                eatNewline();
                inFTLHeader = false;
            }
            SwitchTo(DEFAULT);
        }
    }
    |
    <OPEN_PAREN : "(">
    {
        ++parenthesisNesting;
        if (parenthesisNesting == 1) SwitchTo(IN_PAREN);
    }
    |
    <CLOSE_PAREN : ")">
    {
        --parenthesisNesting;
        if (parenthesisNesting == 0) {
            if (inInvocation) SwitchTo(NAMED_PARAMETER_EXPRESSION);
            else SwitchTo(FM_EXPRESSION);
        }
    }
    |
    <OPENING_CURLY_BRACKET : "{">
    {
        ++curlyBracketNesting;
    }
    |
    <CLOSING_CURLY_BRACKET : "}">
    {
        if (curlyBracketNesting > 0) {
            --curlyBracketNesting;
        } else if (interpolationSyntax != SQUARE_BRACKET_INTERPOLATION_SYNTAX && postInterpolationLexState != -1) {
            endInterpolation(matchedToken);
        } else {
            throw newUnexpectedClosingTokenException(matchedToken);
        }
    }
    |
    <IN : "in">
    |
    <AS : "as">
    |
    <USING : "using">
    |
    <ID: <ID_START_CHAR> (<ID_START_CHAR>|<ASCII_DIGIT>)*> {
        // Remove backslashes from Token.image:
        final String s = matchedToken.image;
        if (s.indexOf('\\') != -1) {
            final int srcLn = s.length();
            final char[] newS = new char[srcLn - 1];
            int dstIdx = 0;
            for (int srcIdx = 0; srcIdx < srcLn; srcIdx++) {
                final char c = s.charAt(srcIdx);
                if (c != '\\') {
                    newS[dstIdx++] = c;
                }
            }
            matchedToken.image = new String(newS, 0, dstIdx);
        }
    }
    |
    <OPEN_MISPLACED_INTERPOLATION : "${" | "#{" | "[=">
    {
        if ("".length() == 0) {  // prevents unreachabe "break" compilation error in generated Java
            char closerC = matchedToken.image.charAt(0) != '[' ? '}' : ']';
            throw new TokenMgrError(
                    "You can't use " + matchedToken.image + "..." + closerC + " (an interpolation) here as you are "
                    + "already in FreeMarker-expression-mode. Thus, instead of " + matchedToken.image + "myExpression"
                    + closerC + ", just write myExpression. (" + matchedToken.image + "..." + closerC + " is only "
                    + "used where otherwise static text is expected, i.e., outside FreeMarker tags and "
                    + "interpolations, or inside string literals.)",
                    TokenMgrError.LEXICAL_ERROR,
                    matchedToken.beginLine, matchedToken.beginColumn,
                    matchedToken.endLine, matchedToken.endColumn);
        }
    }
    |
    <#NON_ESCAPED_ID_START_CHAR:
        [
            // This was generated on JDK 1.8.0_20 Win64 with src/main/misc/identifierChars/IdentifierCharGenerator.java
			"$",
			"@" - "Z",
			"_",
			"a" - "z",
			"\u00AA",
			"\u00B5",
			"\u00BA",
			"\u00C0" - "\u00D6",
			"\u00D8" - "\u00F6",
			"\u00F8" - "\u1FFF",
			"\u2071",
			"\u207F",
			"\u2090" - "\u209C",
			"\u2102",
			"\u2107",
			"\u210A" - "\u2113",
			"\u2115",
			"\u2119" - "\u211D",
			"\u2124",
			"\u2126",
			"\u2128",
			"\u212A" - "\u212D",
			"\u212F" - "\u2139",
			"\u213C" - "\u213F",
			"\u2145" - "\u2149",
			"\u214E",
			"\u2183" - "\u2184",
			"\u2C00" - "\u2C2E",
			"\u2C30" - "\u2C5E",
			"\u2C60" - "\u2CE4",
			"\u2CEB" - "\u2CEE",
			"\u2CF2" - "\u2CF3",
			"\u2D00" - "\u2D25",
			"\u2D27",
			"\u2D2D",
			"\u2D30" - "\u2D67",
			"\u2D6F",
			"\u2D80" - "\u2D96",
			"\u2DA0" - "\u2DA6",
			"\u2DA8" - "\u2DAE",
			"\u2DB0" - "\u2DB6",
			"\u2DB8" - "\u2DBE",
			"\u2DC0" - "\u2DC6",
			"\u2DC8" - "\u2DCE",
			"\u2DD0" - "\u2DD6",
			"\u2DD8" - "\u2DDE",
			"\u2E2F",
			"\u3005" - "\u3006",
			"\u3031" - "\u3035",
			"\u303B" - "\u303C",
			"\u3040" - "\u318F",
			"\u31A0" - "\u31BA",
			"\u31F0" - "\u31FF",
			"\u3300" - "\u337F",
			"\u3400" - "\u4DB5",
			"\u4E00" - "\uA48C",
			"\uA4D0" - "\uA4FD",
			"\uA500" - "\uA60C",
			"\uA610" - "\uA62B",
			"\uA640" - "\uA66E",
			"\uA67F" - "\uA697",
			"\uA6A0" - "\uA6E5",
			"\uA717" - "\uA71F",
			"\uA722" - "\uA788",
			"\uA78B" - "\uA78E",
			"\uA790" - "\uA793",
			"\uA7A0" - "\uA7AA",
			"\uA7F8" - "\uA801",
			"\uA803" - "\uA805",
			"\uA807" - "\uA80A",
			"\uA80C" - "\uA822",
			"\uA840" - "\uA873",
			"\uA882" - "\uA8B3",
			"\uA8D0" - "\uA8D9",
			"\uA8F2" - "\uA8F7",
			"\uA8FB",
			"\uA900" - "\uA925",
			"\uA930" - "\uA946",
			"\uA960" - "\uA97C",
			"\uA984" - "\uA9B2",
			"\uA9CF" - "\uA9D9",
			"\uAA00" - "\uAA28",
			"\uAA40" - "\uAA42",
			"\uAA44" - "\uAA4B",
			"\uAA50" - "\uAA59",
			"\uAA60" - "\uAA76",
			"\uAA7A",
			"\uAA80" - "\uAAAF",
			"\uAAB1",
			"\uAAB5" - "\uAAB6",
			"\uAAB9" - "\uAABD",
			"\uAAC0",
			"\uAAC2",
			"\uAADB" - "\uAADD",
			"\uAAE0" - "\uAAEA",
			"\uAAF2" - "\uAAF4",
			"\uAB01" - "\uAB06",
			"\uAB09" - "\uAB0E",
			"\uAB11" - "\uAB16",
			"\uAB20" - "\uAB26",
			"\uAB28" - "\uAB2E",
			"\uABC0" - "\uABE2",
			"\uABF0" - "\uABF9",
			"\uAC00" - "\uD7A3",
			"\uD7B0" - "\uD7C6",
			"\uD7CB" - "\uD7FB",
			"\uF900" - "\uFB06",
			"\uFB13" - "\uFB17",
			"\uFB1D",
			"\uFB1F" - "\uFB28",
			"\uFB2A" - "\uFB36",
			"\uFB38" - "\uFB3C",
			"\uFB3E",
			"\uFB40" - "\uFB41",
			"\uFB43" - "\uFB44",
			"\uFB46" - "\uFBB1",
			"\uFBD3" - "\uFD3D",
			"\uFD50" - "\uFD8F",
			"\uFD92" - "\uFDC7",
			"\uFDF0" - "\uFDFB",
			"\uFE70" - "\uFE74",
			"\uFE76" - "\uFEFC",
			"\uFF10" - "\uFF19",
			"\uFF21" - "\uFF3A",
			"\uFF41" - "\uFF5A",
			"\uFF66" - "\uFFBE",
			"\uFFC2" - "\uFFC7",
			"\uFFCA" - "\uFFCF",
			"\uFFD2" - "\uFFD7",
			"\uFFDA" - "\uFFDC"
        ]
    >
    |
    // Keep this in sync with StringUtil.isBackslashEscapedFTLIdentifierCharacter
    <#ESCAPED_ID_CHAR: "\\" ("-" | "." | ":" | "#")>
    |
    <#ID_START_CHAR: <NON_ESCAPED_ID_START_CHAR>|<ESCAPED_ID_CHAR>>
    |
    <#ASCII_DIGIT: ["0" - "9"]>
}

<FM_EXPRESSION, NO_SPACE_EXPRESSION, NAMED_PARAMETER_EXPRESSION> TOKEN :
{
    <DIRECTIVE_END : ">">
    {
        if (inFTLHeader) {
	        eatNewline();
	        inFTLHeader = false;
        }
        if (squBracTagSyntax || postInterpolationLexState != -1 /* We are in an interpolation */) {
            matchedToken.kind = NATURAL_GT;
        } else {
            SwitchTo(DEFAULT);
        }
    }
    |
    <EMPTY_DIRECTIVE_END : "/>" | "/]">
    {
        if (tagSyntaxEstablished && (incompatibleImprovements >= _VersionInts.V_2_3_28
                || interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX)) {
            String image = matchedToken.image;
            char lastChar = image.charAt(image.length() - 1);
            if (!squBracTagSyntax && lastChar != '>' || squBracTagSyntax && lastChar != ']') {
                throw new TokenMgrError(
                        "The tag shouldn't end with \"" + lastChar + "\".",
                        TokenMgrError.LEXICAL_ERROR,
                        matchedToken.beginLine, matchedToken.beginColumn,
                        matchedToken.endLine, matchedToken.endColumn);
            }
        }
    
        if (inFTLHeader) {
	        eatNewline();
	        inFTLHeader = false;
        }
        SwitchTo(DEFAULT);
    }
}

<IN_PAREN> TOKEN :
{
    <NATURAL_GT : ">">
    |
    <NATURAL_GTE : ">=">
}

<NO_SPACE_EXPRESSION> TOKEN :
{
    <TERMINATING_WHITESPACE :  (["\n", "\r", "\t", " "])+> : FM_EXPRESSION
}

<NAMED_PARAMETER_EXPRESSION> TOKEN :
{
    <TERMINATING_EXCLAM : "!" (["\n", "\r", "\t", " "])+> : FM_EXPRESSION
}

<NO_PARSE> TOKEN :
{
    <TERSE_COMMENT_END : "-->" | "--]">
    {
        if (noparseTag.equals("-->")) {
            boolean squareBracket = matchedToken.image.endsWith("]");
            if ((squBracTagSyntax && squareBracket) || (!squBracTagSyntax && !squareBracket)) {
                matchedToken.image = matchedToken.image + ";"; 
                SwitchTo(DEFAULT);
            }
        }
    }
    |
    <MAYBE_END :
        ("<" | "[")
        "/"
        ("#")?
        (["a"-"z", "A"-"Z"])+
        ( " " | "\t" | "\n" | "\r" )*
        (">" | "]")
    >
    {
        StringTokenizer st = new StringTokenizer(image.toString(), " \t\n\r<>[]/#", false);
        if (st.nextToken().equals(noparseTag)) {
            matchedToken.image = matchedToken.image + ";"; 
            SwitchTo(DEFAULT);
        }
    }
    |
    <KEEP_GOING : (~["<", "[", "-"])+>
    |
    <LONE_LESS_THAN_OR_DASH : ["<", "[", "-"]>
}

// Now the actual parsing code, starting
// with the productions for FreeMarker's
// expression syntax.

/**
 * This is the same as OrExpression, since
 * the OR is the operator with the lowest
 * precedence.
 */
Expression Expression() :
{
    Expression exp;
}
{
    exp = OrExpression()
    {
        return exp;
    }
}

/**
 * Should be called HighestPrecedenceExpression.
 * Deals with the operators that have the highest precedence. Also deals with `exp!default` and `exp!`, due to parser
 * tricks needed because of the last.
 */
Expression PrimaryExpression() :
{
    Expression exp;
}
{
    exp = AtomicExpression()
    (
        exp = DotVariable(exp)
        |
        exp = DynamicKey(exp)
        |
        exp = MethodArgs(exp)
        |
        exp = BuiltIn(exp)
        |
        exp = DefaultTo(exp)
        |
        exp = Exists(exp)
    )*
    {
        return exp;
    }
}

/**
 * Lowest level expression, a literal, a variable,
 * or a possibly more complex expression bounded
 * by parentheses.
 */
Expression AtomicExpression() :
{
    Expression exp;
}
{
    (
        exp = NumberLiteral()
        |   
        exp = HashLiteral()
        |   
        exp = StringLiteral(true)
        |   
        exp = BooleanLiteral()
        |   
        exp = ListLiteral()
        |   
        exp = Identifier()
        |   
        exp = Parenthesis()
        |   
        exp = BuiltinVariable()
    )
    {
        return exp;
    }
}

Expression Parenthesis() :
{
    Expression exp, result;
    Token start, end;
}
{
    start = <OPEN_PAREN>
    exp = Expression()
    end = <CLOSE_PAREN>
    {
        result = new ParentheticalExpression(exp);
        result.setLocation(template, start, end);
        return result;
    }
}

/**
 * Should be called UnaryPrefixExpression.
 * A primary expression preceded by zero or more unary prefix operators.
 */
Expression UnaryExpression() :
{
    Expression exp, result;
    boolean haveNot = false;
    Token t = null, start = null;
}
{
    (
        result = UnaryPlusMinusExpression()
        |
        result = NotExpression()
        |
        result = PrimaryExpression()
    )
    {
        return result;
    }
}

Expression NotExpression() : 
{
    Token t;
    Expression exp, result = null;
    ArrayList nots = new ArrayList();
}
{
    (
        t = <EXCLAM> { nots.add(t); }
    )+
    exp = PrimaryExpression()
    {
        for (int i = 0; i < nots.size(); i++) {
            result = new NotExpression(exp);
            Token tok = (Token) nots.get(nots.size() -i -1);
            result.setLocation(template, tok, exp);
            exp = result;
        }
        return result;
    }
}

Expression UnaryPlusMinusExpression() :
{
    Expression exp, result;
    boolean isMinus = false;
    Token t;
}
{
    (
        t = <PLUS>
        |
        t = <MINUS> { isMinus = true; }
    )
    exp = PrimaryExpression()
    {
        result = new UnaryPlusMinusExpression(exp, isMinus);  
        result.setLocation(template, t, exp);
        return result;
    }
}

Expression AdditiveExpression() :
{
    Expression lhs, rhs, result;
    boolean plus;
}
{
    lhs = MultiplicativeExpression() { result = lhs; }
    (
        LOOKAHEAD(<PLUS>|<MINUS>)
        (
            (
                <PLUS> { plus = true; }
                |
                <MINUS> { plus = false; }
            )
        )
        rhs = MultiplicativeExpression()
        {
            if (plus) {
	            // plus is treated separately, since it is also
	            // used for concatenation.
                result = new AddConcatExpression(lhs, rhs);
            } else {
                numberLiteralOnly(lhs);
                numberLiteralOnly(rhs);
                result = new ArithmeticExpression(lhs, rhs, ArithmeticExpression.TYPE_SUBSTRACTION);
            }
            result.setLocation(template, lhs, rhs);
            lhs = result;
        }
    )*
    {
        return result;
    }
}

/**
 * A unary prefix expression followed by zero or more
 * unary prefix expressions with operators in between.
 */
Expression MultiplicativeExpression() :
{
    Expression lhs, rhs, result;
    int operation = ArithmeticExpression.TYPE_MULTIPLICATION;
}
{
    lhs = UnaryExpression() { result = lhs; }
    (
        LOOKAHEAD(<TIMES>|<DIVIDE>|<PERCENT>)
        (
            (
                <TIMES> { operation = ArithmeticExpression.TYPE_MULTIPLICATION; }
                |
                <DIVIDE> { operation = ArithmeticExpression.TYPE_DIVISION; }
                |
                <PERCENT> {operation = ArithmeticExpression.TYPE_MODULO; }
            )
        )
        rhs = UnaryExpression()
        {
            numberLiteralOnly(lhs);
            numberLiteralOnly(rhs);
            result = new ArithmeticExpression(lhs, rhs, operation);
            result.setLocation(template, lhs, rhs);
            lhs = result;
        }
    )*
    {
        return result;
    }
}


Expression EqualityExpression() :
{
    Expression lhs, rhs, result;
    Token t;
}
{
    lhs = RelationalExpression() { result = lhs; }
    [
        LOOKAHEAD(<NOT_EQUALS>|<EQUALS>|<DOUBLE_EQUALS>)
        (
            t = <NOT_EQUALS> 
            |
            t = <EQUALS> 
            |
            t = <DOUBLE_EQUALS>
        )
        rhs = RelationalExpression()
        {
	        notHashLiteral(lhs, "different type for equality check");
	        notHashLiteral(rhs, "different type for equality check");
	        notListLiteral(lhs, "different type for equality check");
	        notListLiteral(rhs, "different type for equality check");
	        result = new ComparisonExpression(lhs, rhs, t.image);
	        result.setLocation(template, lhs, rhs);
        }
    ]
    {
        return result;
    }
}

Expression RelationalExpression() :
{
    Expression lhs, rhs, result;
    Token t;
}
{
    lhs = RangeExpression() { result = lhs; }
    [
        LOOKAHEAD(<NATURAL_GTE>|<ESCAPED_GTE>|<NATURAL_GT>|<ESCAPED_GT>|<LESS_THAN_EQUALS>|<LESS_THAN_EQUALS>|<LESS_THAN>)
        (
            t = <NATURAL_GTE>
            |
            t = <ESCAPED_GTE>
            |
            t = <NATURAL_GT>
            |
            t = <ESCAPED_GT>
            |
            t = <LESS_THAN_EQUALS>
            |
            t = <LESS_THAN>
        )
        rhs = RangeExpression()
        {
            numberLiteralOnly(lhs);
            numberLiteralOnly(rhs);
            result = new ComparisonExpression(lhs, rhs, t.image);
            result.setLocation(template, lhs, rhs);
        }
    ]
    {
        return result;
    }
}

Expression RangeExpression() :
{
    Expression lhs, rhs = null, result;
    int endType;
    Token dotDot = null;
}
{
    lhs = AdditiveExpression() { result = lhs; }
    [
        LOOKAHEAD(1)  // To suppress warning
        (
            (
                (
                    <DOT_DOT_LESS> { endType = Range.END_EXCLUSIVE; }
                    |
                    <DOT_DOT_ASTERISK> { endType = Range.END_SIZE_LIMITED; }
                )
                rhs = AdditiveExpression()
            )
            | 
            (
                dotDot = <DOT_DOT> { endType = Range.END_UNBOUND; }
                [
                    LOOKAHEAD(AdditiveExpression())
                    rhs = AdditiveExpression()
                    {
                        endType = Range.END_INCLUSIVE;
                    }
                ]
            )
        )
        {
            numberLiteralOnly(lhs);
            if (rhs != null) {
                numberLiteralOnly(rhs);
            }
           
            Range range = new Range(lhs, rhs, endType);
            if (rhs != null) {
                range.setLocation(template, lhs, rhs);
            } else {
                range.setLocation(template, lhs, dotDot);
            }
            result = range;
        }
    ]
    {
        return result;
    }
}

Expression AndExpression() :
{
    Expression lhs, rhs, result;
}
{
    lhs = EqualityExpression() { result = lhs; }
    (
        LOOKAHEAD(<AND>)
        <AND>
        rhs = EqualityExpression()
        {
            booleanLiteralOnly(lhs);
            booleanLiteralOnly(rhs);
            result = new AndExpression(lhs, rhs);
            result.setLocation(template, lhs, rhs);
            lhs = result;
        }
    )*
    {
        return result;
    }
}

Expression OrExpression() :
{
    Expression lhs, rhs, result;
}
{
    lhs = AndExpression() { result = lhs; }
    (
        LOOKAHEAD(<OR>)
        <OR>
        rhs = AndExpression()
        {
            booleanLiteralOnly(lhs);
            booleanLiteralOnly(rhs);
            result = new OrExpression(lhs, rhs);
            result.setLocation(template, lhs, rhs);
            lhs = result;
        }
    )*
    {
        return result;
    }
}

ListLiteral ListLiteral() :
{
    ArrayList values = new ArrayList();
    Token begin, end;
}
{
    begin = <OPEN_BRACKET>
    values = PositionalArgs()
    end = <CLOSE_BRACKET>
    {
        ListLiteral result = new ListLiteral(values);
        result.setLocation(template, begin, end);
        return result;
    }
}

Expression NumberLiteral() :
{
    Token op = null, t;
}
{
    (
        t = <INTEGER>
        |
        t = <DECIMAL>
    )
    {
        String s = t.image;
        Expression result = new NumberLiteral(pCfg.getArithmeticEngine().toNumber(s));
        Token startToken = (op != null) ? op : t;
        result.setLocation(template, startToken, t);
        return result;
    }
}

Identifier Identifier() :
{
    Token t;
}
{
    t = <ID>
    {
        Identifier id = new Identifier(t.image);
        id.setLocation(template, t, t);
        return id;
    }
}

Expression IdentifierOrStringLiteral() :
{
    Expression exp;
}
{
    (
        exp = Identifier()
        |
        exp = StringLiteral(false)
    )
    {
        return exp;
    }   
}

BuiltinVariable BuiltinVariable() :
{
    Token dot, name;
}
{
    dot = <DOT>
    name = <ID>
    {
        BuiltinVariable result = null;
        token_source.checkNamingConvention(name);

        TemplateModel parseTimeValue;
        String nameStr = name.image;
        if (nameStr.equals(BuiltinVariable.OUTPUT_FORMAT) || nameStr.equals(BuiltinVariable.OUTPUT_FORMAT_CC)) {
            parseTimeValue = new SimpleScalar(outputFormat.getName());
        } else if (nameStr.equals(BuiltinVariable.AUTO_ESC) || nameStr.equals(BuiltinVariable.AUTO_ESC_CC)) {
            parseTimeValue = autoEscaping ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
        } else if (nameStr.equals(BuiltinVariable.ARGS)) {
            if (!inMacro && !inFunction) {
                throw new ParseException("The \"" + BuiltinVariable.ARGS + "\" special variable must be "
                        + "inside a macro or function in the template source code.", template, name);
            }
            requireArgsSpecialVariable = true;
            parseTimeValue = null;
        } else {
            parseTimeValue = null;
        }
        
        result = new BuiltinVariable(name, token_source, parseTimeValue);
        
        result.setLocation(template, dot, name);
        return result;
    }
}

Expression DefaultTo(Expression exp) :
{
    Expression rhs = null;
    Token t;
}
{
    (
        t = <TERMINATING_EXCLAM>
        |
        (
            t = <EXCLAM>
            [
                LOOKAHEAD(Expression())
                rhs = Expression()
            ]
        )
    )
    {
        DefaultToExpression result = new DefaultToExpression(exp, rhs);
        if (rhs == null) {
            // <TERMINATING_EXCLAM> contains the whitespace after the `!`, so we have to use the t.beginXxx:
            result.setLocation(template, exp.beginColumn, exp.beginLine, t.beginColumn, t.beginLine);
        } else {
            result.setLocation(template, exp, rhs);
        }
        return result;
    }
}

Expression Exists(Expression exp) :
{
    Token t;
}
{
    t = <EXISTS>
    {
        ExistsExpression result = new ExistsExpression(exp);
        result.setLocation(template, exp, t);
        return result;
    }
}

Expression BuiltIn(Expression lhoExp) :
{
    Token t = null;
    BuiltIn result;
    ArrayList<Expression> args = null;
    Token openParen;
    Token closeParen;
    MethodCall methodCall;
}
{
    <BUILT_IN>
    t = <ID>
    {
        token_source.checkNamingConvention(t);
        result = BuiltIn.newBuiltIn(incompatibleImprovements, lhoExp, t, token_source);
        result.setLocation(template, lhoExp, t);
        
        if (!(result instanceof SpecialBuiltIn)) {
            return result;
        }

        if (result instanceof BuiltInForLoopVariable) {
            if (!(lhoExp instanceof Identifier)) {
                throw new ParseException(
                        "Expression used as the left hand operand of ?" + t.image
                        + " must be a simple loop variable name.", lhoExp);
            }
            String loopVarName = ((Identifier) lhoExp).getName();
            checkLoopVariableBuiltInLHO(loopVarName, lhoExp, t);
            ((BuiltInForLoopVariable) result).bindToLoopVariable(loopVarName);
            
            return result;
        }
        
        if (result instanceof BuiltInBannedWhenAutoEscaping) {
	    if (outputFormat instanceof MarkupOutputFormat && autoEscaping) {
	        throw new ParseException(
	                "Using ?" + t.image + " (legacy escaping) is not allowed when auto-escaping is on with "
	                + "a markup output format (" + outputFormat.getName() + "), to avoid double-escaping mistakes.",
	                template, t);
	    }
            
            return result;
        }

        if (result instanceof BuiltInBannedWhenForcedAutoEscaping) {
            if (autoEscapingPolicy == Configuration.FORCE_AUTO_ESCAPING_POLICY) {
                throw new ParseException(
                        forcedAutoEscapingPolicyExceptionMessage("The ?" + t.image + " expression"),
                        template, t);
            }
        }

        if (result instanceof MarkupOutputFormatBoundBuiltIn) {
            if (!(outputFormat instanceof MarkupOutputFormat)) {
                throw new ParseException(
                        "?" + t.image + " can't be used here, as the current output format isn't a markup (escaping) "
                        + "format: " + outputFormat, template, t);
            }
            ((MarkupOutputFormatBoundBuiltIn) result).bindToMarkupOutputFormat((MarkupOutputFormat) outputFormat);
            
            return result;
        }

        if (result instanceof OutputFormatBoundBuiltIn) {
            ((OutputFormatBoundBuiltIn) result).bindToOutputFormat(outputFormat, autoEscapingPolicy);
            
            return result;
        }
    }

    [
        LOOKAHEAD({
                result instanceof BuiltInWithParseTimeParameters
                && !((BuiltInWithParseTimeParameters) result).isLocalLambdaParameterSupported() })
        openParen = <OPEN_PAREN>
        args = PositionalArgs()
        closeParen = <CLOSE_PAREN> {
            result.setLocation(template, lhoExp, closeParen);
            ((BuiltInWithParseTimeParameters) result).bindToParameters(args, openParen, closeParen);

            return result;
        }
    ]
    // In principle we should embed the BuiltInWithParseTimeParameters LOOKAHEAD into the
    // isLocalLambdaParameterSupported LOOKAHEAD, but then the `result` variable was out of scope in the code
    // generated for the nested LOOKAHEAD. So we had to flatten this by checking isLocalLambdaParameterSupported twice.
    [
        LOOKAHEAD({
                result instanceof BuiltInWithParseTimeParameters
                && ((BuiltInWithParseTimeParameters) result).isLocalLambdaParameterSupported() })
        openParen = <OPEN_PAREN>
        args = PositionalMaybeLambdaArgs()
        closeParen = <CLOSE_PAREN> {
            result.setLocation(template, lhoExp, closeParen);
            ((BuiltInWithParseTimeParameters) result).bindToParameters(args, openParen, closeParen);

            return result;
        }
    ]

    [
        LOOKAHEAD(<OPEN_PAREN>, { result instanceof BuiltInWithDirectCallOptimization })
        methodCall = MethodArgs(result)
        {
            ((BuiltInWithDirectCallOptimization) result).setDirectlyCalled();
            return methodCall;
        }
    ]

    {
        if (result instanceof BuiltInWithDirectCallOptimization) {
            // We had no (...)
            return result;
        }

        // Should have already return-ed
        throw new AssertionError("Unhandled " + SpecialBuiltIn.class.getName() + " subclass: " + result.getClass());
    }

}

// Only supported as the argument of certain built-ins, so it's not called inside Expression.
Expression LocalLambdaExpression() :
{
    LambdaParameterList lhs;
    Expression rhs, result;
}
{
    (
        LOOKAHEAD(LambdaExpressionParameterList() <LAMBDA_ARROW>)
        (
            lhs = LambdaExpressionParameterList()
            <LAMBDA_ARROW>
            rhs = OrExpression()
            {
    result = new LocalLambdaExpression(lhs, rhs);
    if (lhs.getOpeningParenthesis() != null) {
        // (args) -> exp
        result.setLocation(template, lhs.getOpeningParenthesis(), rhs);
    } else {
        // singleArg -> exp
        result.setLocation(template, lhs.getParameters().get(0), rhs);
    }
}
        )
        |
        result = OrExpression()
    )
    {
        return result;
    }
}

LambdaParameterList LambdaExpressionParameterList() :
{
    Token openParen = null;
    Token closeParen = null;
    List<Identifier> params = null;
    Identifier param;
}
{
    (
        (
            openParen = <OPEN_PAREN>
            [
                param = Identifier()
                {
                    params = new ArrayList<Identifier>(4);
                    params.add(param);
                }
                (
                    <COMMA>
                    param = Identifier()
                    {
                        params.add(param);
                    }
                )*
            ]
            closeParen = <CLOSE_PAREN>
        )
        |
        param = Identifier()
        {
            params = Collections.<Identifier>singletonList(param);
        }
    )
    {
        return new LambdaParameterList(
                openParen,
                params != null ? params : Collections.<Identifier>emptyList(),
                closeParen);
    }
}

/**
 * production for when a key is specified by {@code <DOT>} + keyname
 */
Expression DotVariable(Expression exp) :
{
    Token t;
}
{
        <DOT>
        (
            t = <ID> | t = <TIMES> | t = <DOUBLE_STAR> 
            |
            (
                t = <LESS_THAN>
                |
                t = <LESS_THAN_EQUALS>
                |
                t = <ESCAPED_GT>
                |
                t = <ESCAPED_GTE>
                |
                t = <FALSE>
                |
                t = <TRUE>
                |
                t = <IN>
                |
                t = <AS>
                |
                t = <USING>
            )
            {
                if (!Character.isLetter(t.image.charAt(0))) {
                    throw new ParseException(t.image + " is not a valid identifier.", template, t);
                }
            }
        )
        {
            notListLiteral(exp, "hash");
            notStringLiteral(exp, "hash");
            notBooleanLiteral(exp, "hash");
            Dot dot = new Dot(exp, t.image);
            dot.setLocation(template, exp, t);
            return dot;
        }
}

/**
 * production for when the key is specified
 * in brackets.
 */
Expression DynamicKey(Expression exp) :
{
    Expression arg;
    Token t;
}
{
    <OPEN_BRACKET>
    arg = Expression()
    t = <CLOSE_BRACKET>
    {
        notBooleanLiteral(exp, "list or hash");
        notNumberLiteral(exp, "list or hash");
        DynamicKeyName dkn = new DynamicKeyName(exp, arg);
        dkn.setLocation(template, exp, t);
        return dkn;
    }
}

/**
 * production for an arglist part of a method invocation.
 */
MethodCall MethodArgs(Expression exp) :
{
        ArrayList args = new ArrayList();
        Token end;
}
{
        <OPEN_PAREN>
        args = PositionalArgs()
        end = <CLOSE_PAREN>
        {
            args.trimToSize();
            MethodCall result = new MethodCall(exp, args);
            result.setLocation(template, exp, end);
            return result;
        }
}

StringLiteral StringLiteral(boolean interpolate) :
{
    Token t;
    boolean raw = false;
}
{
    (
        t = <STRING_LITERAL>
        |
        t = <RAW_STRING> { raw = true; }
    )
    {
        String s;
        // Get rid of the quotes.
        if (raw) {
            s = t.image.substring(2, t.image.length() -1);
        } else {
	        try {
	            s = StringUtil.FTLStringLiteralDec(t.image.substring(1, t.image.length() -1));
	        } catch (ParseException pe) {
	            pe.lineNumber = t.beginLine;
	            pe.columnNumber = t.beginColumn;
	            pe.endLineNumber = t.endLine;
	            pe.endColumnNumber = t.endColumn;
	            throw pe;
	        }
        }
        StringLiteral result = new StringLiteral(s);
        result.setLocation(template, t, t);
        if (interpolate && !raw) {
            // TODO: This logic is broken. It can't handle literals that contains both ${...} and $\{...}. 
            int interpolationSyntax = pCfg.getInterpolationSyntax();
            if ((interpolationSyntax == LEGACY_INTERPOLATION_SYNTAX
                    || interpolationSyntax == DOLLAR_INTERPOLATION_SYNTAX)
	                    && t.image.indexOf("${") != -1
	                || interpolationSyntax == LEGACY_INTERPOLATION_SYNTAX
	                    && t.image.indexOf("#{") != -1
	                || interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX
	                    && t.image.indexOf("[=") != -1) {
                result.parseValue(this, outputFormat);
            }
        }
        return result;
    }
}

Expression BooleanLiteral() :
{
    Token t;
    Expression result;
}
{
    (
        t = <FALSE> { result = new BooleanLiteral(false); }
        |
        t = <TRUE> { result = new BooleanLiteral(true); }
    )
    {
        result.setLocation(template, t, t);
        return result;
    }
}


HashLiteral HashLiteral() :
{
    Token begin, end;
    Expression key, value;
    ArrayList<Expression> keys = new ArrayList<Expression>();
    ArrayList<Expression> values = new ArrayList<Expression>();
}
{
    begin = <OPENING_CURLY_BRACKET>
    [
        key = Expression()
        (<COMMA>|<COLON>)
        value = Expression()
        {
            stringLiteralOnly(key);
            keys.add(key);
            values.add(value);
        }
        (
            <COMMA>
            key = Expression()
            (<COMMA>|<COLON>)
            value = Expression()
            {
                stringLiteralOnly(key);
                keys.add(key);
                values.add(value);
            }
        )*
    ]
    end = <CLOSING_CURLY_BRACKET>
    {
        keys.trimToSize();
        values.trimToSize();
        HashLiteral result = new HashLiteral(keys, values);
        result.setLocation(template, begin, end);
        return result;
    }
}

/**
 * A production representing the ${...} or [=...] that outputs a variable; should be called NormalInterpolation.
 */
DollarVariable StringOutput() :
{
    Expression exp;
    Token begin, end;
}
{
    (
	    (
	        begin = <DOLLAR_INTERPOLATION_OPENING>
	        exp = Expression()
	        end = <CLOSING_CURLY_BRACKET>
	    )
	    |
	    (
	        begin = <SQUARE_BRACKET_INTERPOLATION_OPENING>
	        exp = Expression()
	        end = <CLOSE_BRACKET>
	    )
    )
    {
        notHashLiteral(exp, NonStringException.STRING_COERCABLE_TYPES_DESC);
        notListLiteral(exp, NonStringException.STRING_COERCABLE_TYPES_DESC);
                    
        DollarVariable result = new DollarVariable(
                exp, escapedExpression(exp),
                outputFormat,
                autoEscaping);
        result.setLocation(template, begin, end);
        return result;
    }
}

/** Should be called NumericalInterpolation */
NumericalOutput NumericalOutput() :
{
    Expression exp;
    Token fmt = null, begin, end;
}
{
    begin = <HASH_INTERPOLATION_OPENING>
    exp = Expression() { numberLiteralOnly(exp); }
    [
        <SEMICOLON>
        fmt = <ID>
    ]
    end = <CLOSING_CURLY_BRACKET>
    {
        MarkupOutputFormat<?> autoEscOF = autoEscaping && outputFormat instanceof MarkupOutputFormat
                ? (MarkupOutputFormat<?>) outputFormat : null;
    
        NumericalOutput result;
        if (fmt != null) {
            int minFrac = -1;  // -1 indicates that the value has not been set
            int maxFrac = -1;

            StringTokenizer st = new StringTokenizer(fmt.image, "mM", true);
            char type = '-';
            while (st.hasMoreTokens()) {
                String token = st.nextToken();
                try {
	                if (type != '-') {
	                    switch (type) {
	                    case 'm':
	                        if (minFrac != -1) throw new ParseException("Invalid formatting string", template, fmt);
	                        minFrac = Integer.parseInt(token);
	                        break;
	                    case 'M':
	                        if (maxFrac != -1) throw new ParseException("Invalid formatting string", template, fmt);
	                        maxFrac = Integer.parseInt(token);
	                        break;
	                    default:
	                        throw new ParseException("Invalid formatting string", template, fmt);
	                    }
	                    type = '-';
	                } else if (token.equals("m")) {
	                    type = 'm';
	                } else if (token.equals("M")) {
	                    type = 'M';
	                } else {
	                    throw new ParseException();
	                }
                } catch (ParseException e) {
                	throw new ParseException("Invalid format specifier " + fmt.image, template, fmt);
                } catch (NumberFormatException e) {
                	throw new ParseException("Invalid number in the format specifier " + fmt.image, template, fmt);
                }
            }

            if (maxFrac == -1) {
	            if (minFrac == -1) {
	                throw new ParseException(
	                		"Invalid format specification, at least one of m and M must be specified!", template, fmt);
	            }
            	maxFrac = minFrac;
            } else if (minFrac == -1) {
            	minFrac = 0;
            }
            if (minFrac > maxFrac) {
            	throw new ParseException(
            			"Invalid format specification, min cannot be greater than max!", template, fmt);
            }
            if (minFrac > 50 || maxFrac > 50) {// sanity check
                throw new ParseException("Cannot specify more than 50 fraction digits", template, fmt);
            }
            result = new NumericalOutput(exp, minFrac, maxFrac, autoEscOF);
        } else {  // if format != null
            result = new NumericalOutput(exp, autoEscOF);
        }
        result.setLocation(template, begin, end);
        return result;
    }
}

TemplateElement If() :
{
    Token start, end, t;
    Expression condition;
    TemplateElements children;
    IfBlock ifBlock;
    ConditionalBlock cblock;
}
{
    start = <IF>
    condition = Expression()
    end = <DIRECTIVE_END>
    children = MixedContentElements()
    {
        cblock = new ConditionalBlock(condition, children, ConditionalBlock.TYPE_IF);
        cblock.setLocation(template, start, end, children);
        ifBlock = new IfBlock(cblock);
    }
    (
        t = <ELSE_IF>
        condition = Expression()
        end = LooseDirectiveEnd()
        children = MixedContentElements()
        {
            cblock = new ConditionalBlock(condition, children, ConditionalBlock.TYPE_ELSE_IF);
            cblock.setLocation(template, t, end, children);
            ifBlock.addBlock(cblock);
        }
    )*
    [
            t = <ELSE>
            children = MixedContentElements()
            {
                cblock = new ConditionalBlock(null, children, ConditionalBlock.TYPE_ELSE);
                cblock.setLocation(template, t, t, children);
                ifBlock.addBlock(cblock);
            }
    ]
    end = <END_IF>
    {
        ifBlock.setLocation(template, start, end);
        return ifBlock;
    }
}

AttemptBlock Attempt() :
{
    Token start, end;
    TemplateElements children;
    RecoveryBlock recoveryBlock;
}
{
    start = <ATTEMPT>
    children = MixedContentElements()
    recoveryBlock = Recover()
    (
        end = <END_RECOVER>
        |
        end = <END_ATTEMPT>
    )
    {
        AttemptBlock result = new AttemptBlock(children, recoveryBlock);
        result.setLocation(template, start, end);
        return result;
    }
}

RecoveryBlock Recover() : 
{
    Token start;
    TemplateElements children;
}
{
    start = <RECOVER>
    children = MixedContentElements()
    {
        RecoveryBlock result = new RecoveryBlock(children);
        result.setLocation(template, start, start, children);
        return result;
    }
}

TemplateElement List() :
{
    Expression exp;
    Token loopVar = null, loopVar2 = null, start, end;
    TemplateElements childrendBeforeElse;
    ElseOfList elseOfList = null;
    ParserIteratorBlockContext iterCtx;
}
{
    start = <LIST>
    exp = Expression()
    [
        <AS>
        loopVar = <ID>
        [
            <COMMA>
            loopVar2 = <ID>
        ]
    ]
    <DIRECTIVE_END>
    {
        iterCtx = pushIteratorBlockContext();
        if (loopVar != null) {
            iterCtx.loopVarName = loopVar.image;
            breakableDirectiveNesting++;
            continuableDirectiveNesting++;
            if (loopVar2 != null) {
                iterCtx.loopVar2Name = loopVar2.image;
                iterCtx.hashListing = true;
                if (iterCtx.loopVar2Name.equals(iterCtx.loopVarName)) {
                    throw new ParseException(
                            "The key and value loop variable names must differ, but both were: " + iterCtx.loopVarName,
                            template, start);
                }
            }
        }
    }
    
    childrendBeforeElse = MixedContentElements()
    {
        if (loopVar != null) {
            breakableDirectiveNesting--;
            continuableDirectiveNesting--;
        } else if (iterCtx.kind != ITERATOR_BLOCK_KIND_ITEMS) {
            throw new ParseException(
                    "#list must have either \"as loopVar\" parameter or nested #items that belongs to it.",
                    template, start);
        }
        popIteratorBlockContext();
    }
    
    [
        elseOfList = ElseOfList()
    ]
    
    end = <END_LIST>
    {
        IteratorBlock list = new IteratorBlock(
                exp,
                loopVar != null ? loopVar.image : null,  // null when we have a nested #items
                loopVar2 != null ? loopVar2.image : null,
                childrendBeforeElse, iterCtx.hashListing, false);
        list.setLocation(template, start, end);

        TemplateElement result;
        if (elseOfList == null) {
            result = list;
        } else {
            result = new ListElseContainer(list, elseOfList);
            result.setLocation(template, start, end);
        }
        return result;
    }
}

ElseOfList ElseOfList() :
{
    Token start;
    TemplateElements children;
}
{
        start = <ELSE>
        children = MixedContentElements()
        {
            ElseOfList result = new ElseOfList(children);
	        result.setLocation(template, start, start, children);
	        return result;
        }
}

IteratorBlock ForEach() :
{
    Expression exp;
    Token loopVar, start, end;
    TemplateElements children;
}
{
    start = <FOREACH>
    loopVar = <ID>
    <IN>
    exp = Expression()
    <DIRECTIVE_END>
    {
        ParserIteratorBlockContext iterCtx = pushIteratorBlockContext();
        iterCtx.loopVarName = loopVar.image;
        iterCtx.kind = ITERATOR_BLOCK_KIND_FOREACH;
        breakableDirectiveNesting++;
        continuableDirectiveNesting++;
    }
    
    children = MixedContentElements()
    
    end = <END_FOREACH>
    {
        breakableDirectiveNesting--;
        continuableDirectiveNesting--;
        popIteratorBlockContext();
                
        IteratorBlock result = new IteratorBlock(exp, loopVar.image, null, children, false, true);
        result.setLocation(template, start, end);
        return result;
    }
}

Items Items() :
{
    Token loopVar, loopVar2 = null, start, end;
    TemplateElements children;
    ParserIteratorBlockContext iterCtx;
}
{
    start = <ITEMS>
    loopVar = <ID>
    [
        <COMMA>
        loopVar2 = <ID>
    ]
    <DIRECTIVE_END>
    {
        iterCtx = peekIteratorBlockContext();
        if (iterCtx == null) {
            throw new ParseException("#items must be inside a #list block.", template, start);
        }
        if (iterCtx.loopVarName != null) {
            String msg;
	        if (iterCtx.kind == ITERATOR_BLOCK_KIND_FOREACH) {
	            msg = forEachDirectiveSymbol() + " doesn't support nested #items.";
	        } else if (iterCtx.kind == ITERATOR_BLOCK_KIND_ITEMS) {
                msg = "Can't nest #items into each other when they belong to the same #list.";
	        } else {
	            msg = "The parent #list of the #items must not have \"as loopVar\" parameter.";
            }
            throw new ParseException(msg, template, start);
        }
        iterCtx.kind = ITERATOR_BLOCK_KIND_ITEMS;
        iterCtx.loopVarName = loopVar.image;
        if (loopVar2 != null) {
            iterCtx.loopVar2Name = loopVar2.image;
            iterCtx.hashListing = true;
            if (iterCtx.loopVar2Name.equals(iterCtx.loopVarName)) {
                throw new ParseException(
                        "The key and value loop variable names must differ, but both were: " + iterCtx.loopVarName,
                        template, start);
            }
        }
    
        breakableDirectiveNesting++;
        continuableDirectiveNesting++;
    }
    
    children = MixedContentElements()
    
    end = <END_ITEMS>
    {
        breakableDirectiveNesting--;
        continuableDirectiveNesting--;
        iterCtx.loopVarName = null;
        iterCtx.loopVar2Name = null;
        
        Items result = new Items(loopVar.image, loopVar2 != null ? loopVar2.image : null, children);
        result.setLocation(template, start, end);
        return result;
    }
}

Sep Sep() :
{
    Token loopVar, start, end = null;
    TemplateElements children;
}
{
    start = <SEP>
    {
        if (peekIteratorBlockContext() == null) {
            throw new ParseException(
                    "#sep must be inside a #list (or " + forEachDirectiveSymbol() + ") block.",
                    template, start);
        }
    }
    children = MixedContentElements()
    [
        LOOKAHEAD(1)
        end = <END_SEP>
    ]
    {
        Sep result = new Sep(children);
        if (end != null) {
            result.setLocation(template, start, end);
        } else {
            result.setLocation(template, start, start, children);
        }
        return result;
    }
}

VisitNode Visit() :
{
    Token start, end;
    Expression targetNode, namespaces = null;
}
{
    start = <VISIT>
    targetNode = Expression()
    [
        <USING>
        namespaces = Expression()
    ]
    end = LooseDirectiveEnd()
    {
        VisitNode result = new VisitNode(targetNode, namespaces);
        result.setLocation(template, start, end);
        return result;
    }
}

RecurseNode Recurse() :
{
    Token start, end = null;
    Expression node = null, namespaces = null;
}
{
    (
        start = <SIMPLE_RECURSE>
        |
        (
            start = <RECURSE>
            [
                node = Expression()
            ]
            [
                <USING>
                namespaces = Expression()
            ]
            end = LooseDirectiveEnd()
        )
    )
    {
        if (end == null) end = start;
        RecurseNode result = new RecurseNode(node, namespaces);
        result.setLocation(template, start, end);
        return result;
    }
}

FallbackInstruction FallBack() :
{
    Token tok;
}
{
    tok = <FALLBACK>
    {
        if (!inMacro) {
            throw new ParseException("Cannot fall back outside a macro.", template, tok);
        }
        FallbackInstruction result = new FallbackInstruction();
        result.setLocation(template, tok, tok);
        return result;
    }
}

/**
 * Production used to break out of a loop or a switch block.
 */
BreakInstruction Break() :
{
    Token start;
}
{
    start = <BREAK>
    {
        if (breakableDirectiveNesting < 1) {
            throw new ParseException(start.image + " must be nested inside a directive that supports it: " 
                    + " #list with \"as\", #items, #switch (or the deprecated " + forEachDirectiveSymbol() + ")",
                    template, start);
        }
        BreakInstruction result = new BreakInstruction();
        result.setLocation(template, start, start);
        return result;
    }
}

/**
 * Production used to skip an iteration in a loop.
 */
ContinueInstruction Continue() :
{
    Token start;
}
{
    start = <CONTINUE>
    {
        if (continuableDirectiveNesting < 1) {
            throw new ParseException(start.image + " must be nested inside a directive that supports it: " 
                    + " #list with \"as\", #items (or the deprecated " + forEachDirectiveSymbol() + ")",
                    template, start);
        }
        ContinueInstruction result = new ContinueInstruction();
        result.setLocation(template, start, start);
        return result;
    }
}

/**
 * Production used to jump out of a macro.
 * The stop instruction terminates the rendering of the template.
 */
ReturnInstruction Return() :
{
    Token start, end = null;
    Expression exp = null;
}
{
    (
        start = <SIMPLE_RETURN> { end = start; }
        |
        start = <RETURN> exp = Expression() end = LooseDirectiveEnd()
    )
    {
        if (inMacro) {
            if (exp != null) {
            	throw new ParseException("A macro cannot return a value", template, start);
            }
        } else if (inFunction) {
            if (exp == null) {
            	throw new ParseException("A function must return a value", template, start);
            }
        } else {
            if (exp == null) {
            	throw new ParseException(
            			"A return instruction can only occur inside a macro or function", template, start);
            }
        }
        ReturnInstruction result = new ReturnInstruction(exp);
        result.setLocation(template, start, end);
        return result;
    }
}

StopInstruction Stop() :
{
    Token start = null;
    Expression exp = null;
}
{
    (
        start = <HALT>
        |
        start = <STOP> exp = Expression() LooseDirectiveEnd()
    )
    {
        StopInstruction result = new StopInstruction(exp);
        result.setLocation(template, start, start);
        return result;
    }
}

TemplateElement Nested() :
{
    Token t, end;
    ArrayList bodyParameters;
    BodyInstruction result = null;
}
{
    (
        (
            t = <SIMPLE_NESTED>
            {
                result = new BodyInstruction(null);
                result.setLocation(template, t, t);
            }
        )
        |
        (
            t = <NESTED>
            bodyParameters = PositionalArgs()
            end = LooseDirectiveEnd()
            {
                result = new BodyInstruction(bodyParameters);
                result.setLocation(template, t, end);
            }
        )
    )
    {
        if (!inMacro) {
            throw new ParseException("Cannot use a " + t.image + " instruction outside a macro.", template, t);
        }
        return result;
    }
}

TemplateElement Flush() :
{
    Token t;
}
{
    t = <FLUSH>
    {
        FlushInstruction result = new FlushInstruction();
        result.setLocation(template, t, t);
        return result;
    }
}

TemplateElement Trim() :
{
    Token t;
    TrimInstruction result = null;
}
{
    (
        t = <TRIM> { result = new TrimInstruction(true, true); }
        |
        t = <LTRIM> { result = new TrimInstruction(true, false); }
        |
        t = <RTRIM> { result = new TrimInstruction(false, true); }
        |
        t = <NOTRIM> { result = new TrimInstruction(false, false); }
    )
    {
        result.setLocation(template, t, t);
        return result;
    }
}


TemplateElement Assign() :
{
    Token start, end;
    int scope;
    Token id = null;
    Token equalsOp;
    Expression nameExp, exp, nsExp = null;
    String varName;
    ArrayList assignments = new ArrayList();
    Assignment ass;
    TemplateElements children;
}
{
    (
        start = <ASSIGN> { scope = Assignment.NAMESPACE; }
        |
        start = <GLOBALASSIGN> { scope = Assignment.GLOBAL; }
        |
        start = <LOCALASSIGN> { scope = Assignment.LOCAL; }
        {
            scope = Assignment.LOCAL;
            if (!inMacro && !inFunction) {
                throw new ParseException("Local variable assigned outside a macro.", template, start);
            }
        }
    )
    nameExp = IdentifierOrStringLiteral()
    {
        varName = (nameExp instanceof StringLiteral)
                ? ((StringLiteral) nameExp).getAsString()
                : ((Identifier) nameExp).getName();
    }
    (
    	(
            (
	    	    (
			        (<EQUALS>|<PLUS_EQUALS>|<MINUS_EQUALS>|<TIMES_EQUALS>|<DIV_EQUALS>|<MOD_EQUALS>)
			        {
			           equalsOp = token;
			        }
			        exp = Expression()
		        )
		        |
		        (
	                (<PLUS_PLUS>|<MINUS_MINUS>)
	                {
	                   equalsOp = token;
	                   exp = null;
	                }
		        )
	        )
	        {
	            ass = new Assignment(varName, equalsOp.kind, exp, scope);
                if (exp != null) {
                   ass.setLocation(template, nameExp, exp);
                } else {
                   ass.setLocation(template, nameExp, equalsOp);
                }
	            assignments.add(ass);
	        }
	        (
	            LOOKAHEAD(
	               [<COMMA>]
	               (<ID>|<STRING_LITERAL>)
	               (<EQUALS>|<PLUS_EQUALS>|<MINUS_EQUALS>|<TIMES_EQUALS>|<DIV_EQUALS>|<MOD_EQUALS>
	                       |<PLUS_PLUS>|<MINUS_MINUS>)
	            )
	            [<COMMA>]
	            nameExp = IdentifierOrStringLiteral()
	            {
	                varName = (nameExp instanceof StringLiteral)
	                		? ((StringLiteral) nameExp).getAsString()
	                		: ((Identifier) nameExp).getName();
	            }
	            (
	                (
	                    (<EQUALS>|<PLUS_EQUALS>|<MINUS_EQUALS>|<TIMES_EQUALS>|<DIV_EQUALS>|<MOD_EQUALS>)
	                    {
	                       equalsOp = token;
	                    }
	                    exp = Expression()
	                )
	                |
	                (
	                    (<PLUS_PLUS>|<MINUS_MINUS>)
	                    {
	                       equalsOp = token;
	                       exp = null;
	                    }
	                )
	            )
	            {
	                ass = new Assignment(varName, equalsOp.kind, exp, scope);
	                if (exp != null) {
	                   ass.setLocation(template, nameExp, exp);
	                } else {
                       ass.setLocation(template, nameExp, equalsOp);
	                }
	                assignments.add(ass);
	            } 
	        )*
	        [
	            id = <IN>
	            nsExp = Expression()
	            {
	                if (scope != Assignment.NAMESPACE) {
	                	throw new ParseException("Cannot assign to namespace here.", template, id);
                	}
	            }
	        ]
	        end = LooseDirectiveEnd()
	        {
                if (assignments.size() == 1) {
                    Assignment a = (Assignment) assignments.get(0);
                    a.setNamespaceExp(nsExp);
                    a.setLocation(template, start, end);
                    return a;
                } else {
		            AssignmentInstruction ai = new AssignmentInstruction(scope);
		            for (int i = 0; i< assignments.size(); i++) {
		                ai.addAssignment((Assignment) assignments.get(i));
		            }
		            ai.setNamespaceExp(nsExp);
		            ai.setLocation(template, start, end);
		            return ai;
	            }
	        }
	    )
	    |
	    (
	        [
	            id = <IN>
	            nsExp = Expression()
	            {
	                if (scope != Assignment.NAMESPACE) {
	                	throw new ParseException("Cannot assign to namespace here.", template, id);
	            	}
	            }
	        ]
	        <DIRECTIVE_END>
	        children = MixedContentElements()
	        (
	            end = <END_LOCAL>
	            {
	            	if (scope != Assignment.LOCAL) {
	            		throw new ParseException("Mismatched assignment tags.", template, end);
	        		}
	        	}
	            |
	            end = <END_ASSIGN>
	            {
	            	if (scope != Assignment.NAMESPACE) {
	            		throw new ParseException("Mismatched assignment tags.", template, end);
	        		}
	        	}
	            |
	            end = <END_GLOBAL>
	            {
	            	if (scope != Assignment.GLOBAL) throw new ParseException(
	            			"Mismatched assignment tags", template, end);
            	}
	        )
	        {
	            BlockAssignment ba = new BlockAssignment(
	                   children, varName, scope, nsExp,
	                   getMarkupOutputFormat());
	            ba.setLocation(template, start, end);
	            return ba;
	        }
	    )
    )
}

Include Include() :
{
    Expression nameExp;
    Token att, start, end;
    Expression exp, parseExp = null, encodingExp = null, ignoreMissingExp = null;
}
{
    start = <_INCLUDE>
    nameExp = Expression()
    [<SEMICOLON>]
    (
        att = <ID>
        <EQUALS>
        exp = Expression()
        {
            String attString = att.image;
            if (attString.equalsIgnoreCase("parse")) {
        	    parseExp = exp;
            } else if (attString.equalsIgnoreCase("encoding")) {
            	encodingExp = exp;
            } else if (attString.equalsIgnoreCase("ignore_missing") || attString.equals("ignoreMissing")) {
                token_source.checkNamingConvention(att);
            	ignoreMissingExp = exp;
            } else {
                String correctedName = attString.equals("ignoreMissing") ? "ignore_missing" : null;
                throw new ParseException(
                		"Unsupported named #include parameter: \"" + attString + "\". Supported parameters are: "
                		+ "\"parse\", \"encoding\", \"ignore_missing\"."
                		+ (correctedName == null
                		      ? ""
                		      : " Supporting camelCase parameter names is planned for FreeMarker 2.4.0; "
	                              + "check if an update is available, and if it indeed supports camel "
	                              + "case."),
                		template, att);
            }
        }
    )*
    end = LooseDirectiveEnd()
    {
        Include result = new Include(template, nameExp, encodingExp, parseExp, ignoreMissingExp);
        result.setLocation(template, start, end);
        return result;
    }
}

LibraryLoad Import() :
{
    Token start, end, ns;
    Expression nameExp;
}
{
    start = <IMPORT>
    nameExp = Expression()
    <AS>
    ns = <ID>
    end = LooseDirectiveEnd()
    {
        LibraryLoad result = new LibraryLoad(template, nameExp, ns.image);
        result.setLocation(template, start, end);
        template.addImport(result);
        return result;
    }
}

Macro Macro() :
{
    Token arg, start, end;
    Expression nameExp;
    String name;
    Map<String, Expression> paramNamesWithDefault = new LinkedHashMap<String, Expression>();
    Expression defValue = null;
    String catchAllParamName = null;
    boolean isCatchAll = false;
    List lastIteratorBlockContexts;
    int lastBreakableDirectiveNesting;
    int lastContinuableDirectiveNesting;
    TemplateElements children;
    boolean isFunction = false;
    boolean hasDefaults = false;
}
{
    (
        start = <MACRO>
        |
        start = <FUNCTION> { isFunction = true; }
    )
    {
        if (inMacro || inFunction) {
            throw new ParseException("Macro or function definitions can't be nested into each other.", template, start);
        }
        if (isFunction) inFunction = true; else inMacro = true;
        requireArgsSpecialVariable = false;
    }
    nameExp = IdentifierOrStringLiteral()
    {
        name = (nameExp instanceof StringLiteral)
                ? ((StringLiteral) nameExp).getAsString()
                : ((Identifier) nameExp).getName();
    }
    [<OPEN_PAREN>]
    (
        arg = <ID> { defValue = null; }
        [
            <ELLIPSIS> { isCatchAll = true; }
        ]
        [
            <EQUALS>
            defValue = Expression()
            {
                hasDefaults = true;
            }
        ]
        [<COMMA>]
        {
            if (catchAllParamName != null) {
                throw new ParseException(
                "There may only be one \"catch-all\" parameter in a macro declaration, and it must be the last parameter.",
                template, arg);
            }
            if (isCatchAll) {
                if (defValue != null) {
                    throw new ParseException(
                    "\"Catch-all\" macro parameter may not have a default value.",
                    template, arg);
                }
                catchAllParamName = arg.image;
            } else {
                if (hasDefaults && defValue == null) {
                    throw new ParseException(
		                    "In a macro declaration, parameters without a default value "
		                    + "must all occur before the parameters with default values.",
                    template, arg);
                }
                paramNamesWithDefault.put(arg.image, defValue);
            }
        }
    )*
    [<CLOSE_PAREN>]
    <DIRECTIVE_END>
    {
        // To prevent parser check loopholes like <#list ...><#macro ...><#break></#macro></#list>.
        lastIteratorBlockContexts = iteratorBlockContexts;
        iteratorBlockContexts = null;
        if (incompatibleImprovements >= _VersionInts.V_2_3_23) {
            lastBreakableDirectiveNesting = breakableDirectiveNesting;
            lastContinuableDirectiveNesting = continuableDirectiveNesting;
            breakableDirectiveNesting = 0;
            continuableDirectiveNesting = 0;
        } else {
            lastBreakableDirectiveNesting = 0; // Just to prevent uninitialized local variable error later
            lastContinuableDirectiveNesting = 0;
        }
    }
    children = MixedContentElements()
    (
        end = <END_MACRO>
        {
        	if (isFunction) throw new ParseException("Expected function end tag here.", template, end);
    	}
        |
        end = <END_FUNCTION>
        {
    		if (!isFunction) throw new ParseException("Expected macro end tag here.", template, end);
    	}
    )
    {
        iteratorBlockContexts = lastIteratorBlockContexts;
        if (incompatibleImprovements >= _VersionInts.V_2_3_23) {
            breakableDirectiveNesting = lastBreakableDirectiveNesting;
            continuableDirectiveNesting = lastContinuableDirectiveNesting;
        }

        inMacro = inFunction = false;
        Macro result = new Macro(
                name, paramNamesWithDefault, catchAllParamName, isFunction, requireArgsSpecialVariable, children);
        result.setLocation(template, start, end);
        template.addMacro(result);
        return result;
    }
}

CompressedBlock Compress() :
{
    TemplateElements children;
    Token start, end;
}
{
    start = <COMPRESS>
    children = MixedContentElements()
    end = <END_COMPRESS>
    {
        CompressedBlock cb = new CompressedBlock(children);
        cb.setLocation(template, start, end);
        return cb;
    }
}

TemplateElement UnifiedMacroTransform() :
{
    Token start = null, end, t;
    HashMap namedArgs = null;
    ArrayList positionalArgs = null, bodyParameters = null;
    Expression startTagNameExp;
    TemplateElements children;
    Expression exp;
    int pushedCtxCount = 0;
}
{
    start = <UNIFIED_CALL>
    exp = Expression()
    {
        // To allow <@foo.bar?withArgs(...)>...</@foo.bar>, but we also remove superfluous (...):
        Expression cleanedExp = exp;
        if (cleanedExp instanceof MethodCall) {
            Expression methodCallTarget = ((MethodCall) cleanedExp).getTarget();
            if (methodCallTarget instanceof BuiltInsForCallables.with_argsBI) {
                cleanedExp = ((BuiltInsForCallables.with_argsBI) methodCallTarget).target;
            }
        }

        if (cleanedExp instanceof Identifier || (cleanedExp instanceof Dot && ((Dot) cleanedExp).onlyHasIdentifiers())) {
            startTagNameExp = cleanedExp;
        } else {
            startTagNameExp = null;
        }
    }
    [<TERMINATING_WHITESPACE>]
    (
        LOOKAHEAD(<ID><EQUALS>)
        namedArgs = NamedArgs()
        |
        positionalArgs = PositionalArgs()
    )
    [
        <SEMICOLON>
        { bodyParameters = new ArrayList(4); }
        [
            [<TERMINATING_WHITESPACE>] t = <ID> { bodyParameters.add(t.image); }
            (
                [<TERMINATING_WHITESPACE>] <COMMA>
                [<TERMINATING_WHITESPACE>] t = <ID> {bodyParameters.add(t.image); }
            )*
        ]
    ]
    (
        end = <EMPTY_DIRECTIVE_END> { children = TemplateElements.EMPTY; }
        |
        (
            <DIRECTIVE_END> {
                if (bodyParameters != null && iteratorBlockContexts != null && !iteratorBlockContexts.isEmpty()) {
                    // It's possible that we shadow a #list/#items loop variable, in which case that must be noted.
                    int ctxsLen = iteratorBlockContexts.size();
                    int bodyParsLen = bodyParameters.size();
	                for (int bodyParIdx = 0; bodyParIdx < bodyParsLen; bodyParIdx++) {
                        String bodyParName = (String) bodyParameters.get(bodyParIdx);
                        walkCtxSack: for (int ctxIdx = ctxsLen - 1; ctxIdx >= 0; ctxIdx--) {
                            ParserIteratorBlockContext ctx
                                    = (ParserIteratorBlockContext) iteratorBlockContexts.get(ctxIdx);
                            if (ctx.loopVarName != null && ctx.loopVarName.equals(bodyParName)) {
                                // If it wasn't already shadowed, shadow it:
                                if (ctx.kind != ITERATOR_BLOCK_KIND_USER_DIRECTIVE) {
                                    ParserIteratorBlockContext shadowingCtx = pushIteratorBlockContext();
                                    shadowingCtx.loopVarName = bodyParName;
                                    shadowingCtx.kind = ITERATOR_BLOCK_KIND_USER_DIRECTIVE;
                                    pushedCtxCount++;
                                }
                                break walkCtxSack;
                            }
                        }
                   }
                }
            }
            children = MixedContentElements()
            end = <UNIFIED_CALL_END>
            {
                for (int i = 0; i < pushedCtxCount; i++) {
                    popIteratorBlockContext();
                }
            
                String endTagName = end.image.substring(3, end.image.length() - 1).trim();
                if (endTagName.length() > 0) {
                    if (startTagNameExp == null) {
                        throw new ParseException("Expecting </@>", template, end);
                    } else {
                        String startTagName = startTagNameExp.getCanonicalForm();
                        if (!endTagName.equals(startTagName)) {
                            throw new ParseException("Expecting </@> or </@" + startTagName + ">", template, end);
                        }
                    }
                }
            }
        )
    )
    {
        TemplateElement result = (positionalArgs != null)
        		? new UnifiedCall(exp, positionalArgs, children, bodyParameters)
	            : new UnifiedCall(exp, namedArgs, children, bodyParameters);
        result.setLocation(template, start, end);
        return result;
    }
}

TemplateElement Call() :
{
    Token start, end, id;
    HashMap namedArgs = null;
    ArrayList positionalArgs = null;
    Identifier macroName= null;
}
{
    start = <CALL>
    id = <ID> {
        macroName = new Identifier(id.image);
        macroName.setLocation(template, id, id);
    }
    (
        LOOKAHEAD(<ID><EQUALS>)
        namedArgs = NamedArgs()
        |
        (
            [
            LOOKAHEAD(<OPEN_PAREN>)
                <OPEN_PAREN>
            ]
            positionalArgs = PositionalArgs()
            [<CLOSE_PAREN>]
        )
    )
    end = LooseDirectiveEnd()
    {
        UnifiedCall result = null;
        if (positionalArgs != null) {
            result = new UnifiedCall(macroName, positionalArgs, TemplateElements.EMPTY, null);
        } else {
            result = new UnifiedCall(macroName, namedArgs, TemplateElements.EMPTY, null);
        }
        result.legacySyntax = true;
        result.setLocation(template, start, end);
        return result;
    }
}

HashMap NamedArgs() :
{
    HashMap result = new HashMap();
    Token t;
    Expression exp;
}
{
    (
        t = <ID>
        <EQUALS>
        {
            token_source.SwitchTo(token_source.NAMED_PARAMETER_EXPRESSION);
            token_source.inInvocation = true;
        }             
        exp = Expression()
        {
            result.put(t.image, exp);
        }
    )+
    {
        token_source.inInvocation = false;
        return result;
    }
}

ArrayList PositionalArgs() :
{
    ArrayList result = new ArrayList();
    Expression arg;
}
{
    [
        arg = Expression() { result.add(arg); }
        (
            [<COMMA>]
            arg = Expression() { result.add(arg); }
        )*
    ]
    {
        return result;
    }
}

/**
 * Like PositionalArgs, but allows lambdas. This is separate as it's slower, while lambdas are only allowed on a few
 * places.
 */
ArrayList PositionalMaybeLambdaArgs() :
{
    ArrayList result = new ArrayList();
    Expression arg;
}
{
    [
        arg = LocalLambdaExpression() { result.add(arg); }
        (
            [<COMMA>]
            arg = LocalLambdaExpression() { result.add(arg); }
        )*
    ]
    {
        return result;
    }
}

Comment Comment() :
{
    Token start, end;
    StringBuilder buf = new StringBuilder();
}
{
    (
        start = <COMMENT>
        |
        start = <TERSE_COMMENT>
    )
    end = UnparsedContent(start, buf)
    {
        Comment result = new Comment(buf.toString());
        result.setLocation(template, start, end);
        return result;
    }
}

TextBlock NoParse() :
{
    Token start, end;
    StringBuilder buf = new StringBuilder();
}
{
    start = <NOPARSE>
    end = UnparsedContent(start, buf)
    {
        TextBlock result = new TextBlock(buf.toString(), true);
        result.setLocation(template, start, end);
        return result;
    }
}

TransformBlock Transform() :
{
    Token start, end, argName;
    Expression exp, argExp;
    TemplateElements children = null;
    HashMap args = null;
}
{
    start = <TRANSFORM>
    exp = Expression()
    [<SEMICOLON>]
    (
        argName = <ID>
        <EQUALS>
        argExp = Expression()
        {
            if (args == null) args = new HashMap();
            args.put(argName.image, argExp);
        }
    )*
    (
        end = <EMPTY_DIRECTIVE_END>
        |
        (
            <DIRECTIVE_END>
            children = MixedContentElements()
            end = <END_TRANSFORM>
        )
    )
    {
        TransformBlock result = new TransformBlock(exp, args, children);
        result.setLocation(template, start, end);
        return result;
    }
}

SwitchBlock Switch() :
{
    SwitchBlock switchBlock;
    MixedContent ignoredSectionBeforeFirstCase = null;
    Case caseIns;
    Expression switchExp;
    Token start, end;
    boolean defaultFound = false;
}
{
    (
	    start = <SWITCH>
	    switchExp = Expression()
	    <DIRECTIVE_END>
        [ ignoredSectionBeforeFirstCase = WhitespaceAndComments() ]
    )
    {
        breakableDirectiveNesting++;
        switchBlock = new SwitchBlock(switchExp, ignoredSectionBeforeFirstCase);
    }
    [
	    (
	        caseIns = Case()
	        {
	            if (caseIns.condition == null) {
	                if (defaultFound) {
	                    throw new ParseException(
	                    "You can only have one default case in a switch statement", template, start);
	                }
	                defaultFound = true;
	            }
	            switchBlock.addCase(caseIns);
	        }
	    )+
	    [<STATIC_TEXT_WS>]
    ]
    end = <END_SWITCH>
    {
        breakableDirectiveNesting--;
        switchBlock.setLocation(template, start, end);
        return switchBlock;
    }
}

Case Case() :
{
    Expression exp;
    TemplateElements children;
    Token start;
}
{
    (
        start = <CASE> exp = Expression() <DIRECTIVE_END>
        |
        start = <DEFAUL> { exp = null; }
    )
    children = MixedContentElements()
    {
        Case result = new Case(exp, children);
        result.setLocation(template, start, start, children);
        return result;
    }
}

EscapeBlock Escape() :
{
    Token variable, start, end;
    Expression escapeExpr;
    TemplateElements children;
}
{
    start = <ESCAPE>
    {
        if (outputFormat instanceof MarkupOutputFormat && autoEscaping) {
            throw new ParseException(
                    "Using the \"escape\" directive (legacy escaping) is not allowed when auto-escaping is on with "
                    + "a markup output format (" + outputFormat.getName()
                    + "), to avoid confusion and double-escaping mistakes.",
                    template, start);
        }
    }
    variable = <ID>
    <AS>
    escapeExpr = Expression()
    <DIRECTIVE_END>
    {
        EscapeBlock result = new EscapeBlock(variable.image, escapeExpr, escapedExpression(escapeExpr));
        escapes.addFirst(result);
    }
    children = MixedContentElements()
    {
        result.setContent(children);
        escapes.removeFirst();
    }
    end = <END_ESCAPE>
    {
        result.setLocation(template, start, end);
        return result;
    }
}

NoEscapeBlock NoEscape() :
{
    Token start, end;
    TemplateElements children;
}
{
    start = <NOESCAPE>
    {
        if (escapes.isEmpty()) {
            throw new ParseException("#noescape with no matching #escape encountered.", template, start);
        }
        Object escape = escapes.removeFirst();
    }
    children = MixedContentElements()
    end = <END_NOESCAPE>
    {
        escapes.addFirst(escape);
        NoEscapeBlock result = new NoEscapeBlock(children);
        result.setLocation(template, start, end);
        return result;
    }
}

OutputFormatBlock OutputFormat() :
{
    Token start, end;
    Expression paramExp;
    TemplateElements children;
    OutputFormat lastOutputFormat;
}
{
    start = <OUTPUTFORMAT>
    paramExp = Expression()
    <DIRECTIVE_END>
    {
        if (!paramExp.isLiteral()) {
            throw new ParseException(
                    "Parameter expression must be parse-time evaluable (constant): "
                    + paramExp.getCanonicalForm(),
                    paramExp);
        }
    
        TemplateModel paramTM;
        try {
            paramTM = paramExp.eval(null);
        } catch (Exception e) {
            throw new ParseException(
                    "Could not evaluate expression (on parse-time): " + paramExp.getCanonicalForm()
                    + "\nUnderlying cause: " +  e,
                    paramExp, e);
        }
        String paramStr;
        if (paramTM instanceof TemplateScalarModel) {
            try {
                paramStr = ((TemplateScalarModel) paramTM).getAsString();
            } catch (TemplateModelException e) {
	            throw new ParseException(
	                    "Could not evaluate expression (on parse-time): " + paramExp.getCanonicalForm()
	                    + "\nUnderlying cause: " +  e,
	                    paramExp, e);
            }
        } else {
            throw new ParseException(
                    "Parameter must be a string, but was: " + ClassUtil.getFTLTypeDescription(paramTM),
                    paramExp);
        }
        
        lastOutputFormat = outputFormat;
        try { 
            if (paramStr.startsWith("{")) {
                if (!paramStr.endsWith("}")) {
                    throw new ParseException("Output format name that starts with '{' must end with '}': " + paramStr,
                            template, start);
                }
                OutputFormat innerOutputFormat = template.getConfiguration().getOutputFormat(
                        paramStr.substring(1, paramStr.length() - 1));
                if (!(innerOutputFormat instanceof MarkupOutputFormat)) {
                    throw new ParseException(
                            "The output format inside the {...} must be a markup format, but was: "
                            + innerOutputFormat,
                            template, start);
                }
                if (!(outputFormat instanceof MarkupOutputFormat)) {
                    throw new ParseException(
                            "The current output format must be a markup format when using {...}, but was: "
                            + outputFormat,
                            template, start);
                }
                outputFormat = new CombinedMarkupOutputFormat(
                        (MarkupOutputFormat) outputFormat, (MarkupOutputFormat) innerOutputFormat);
            } else {
                outputFormat = template.getConfiguration().getOutputFormat(paramStr);
            }
            if (!(outputFormat instanceof MarkupOutputFormat)
                    && autoEscapingPolicy == Configuration.FORCE_AUTO_ESCAPING_POLICY) {
                throw new ParseException(forcedAutoEscapingPolicyExceptionMessage(outputFormat), template, start);
            }
            recalculateAutoEscapingField();
        } catch (IllegalArgumentException e) {
            throw new ParseException("Invalid format name: " + e.getMessage(), template, start, e.getCause());
        } catch (UnregisteredOutputFormatException e) {
            throw new ParseException(e.getMessage(), template, start, e.getCause());
        }
    }
    children = MixedContentElements()
    end = <END_OUTPUTFORMAT>
    {
        OutputFormatBlock result = new OutputFormatBlock(children, paramExp);
        result.setLocation(template, start, end);
        
        outputFormat = lastOutputFormat;
        recalculateAutoEscapingField();         
        return result;
    }
}

AutoEscBlock AutoEsc() :
{
    Token start, end;
    TemplateElements children;
    int lastAutoEscapingPolicy;
}
{
    start = <AUTOESC>
    {
        checkCurrentOutputFormatCanEscape(start);
        lastAutoEscapingPolicy = autoEscapingPolicy;
        autoEscapingPolicy = Configuration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY;
        recalculateAutoEscapingField();
    }
    children = MixedContentElements()
    end = <END_AUTOESC>
    {
        AutoEscBlock result = new AutoEscBlock(children);
        result.setLocation(template, start, end);
        
        autoEscapingPolicy = lastAutoEscapingPolicy; 
        recalculateAutoEscapingField();
        return result;
    }
}

NoAutoEscBlock NoAutoEsc() :
{
    Token start, end;
    TemplateElements children;
    int lastAutoEscapingPolicy;
}
{
    start = <NOAUTOESC>
    {
        if (autoEscapingPolicy == Configuration.FORCE_AUTO_ESCAPING_POLICY) {
            throw new ParseException(
                    forcedAutoEscapingPolicyExceptionMessage(
                            "<#" + (token_source.namingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION ? "noAutoEsc" : "noautoesc") + ">"),
                    template, start);
        }
        lastAutoEscapingPolicy = autoEscapingPolicy;
        autoEscapingPolicy = Configuration.DISABLE_AUTO_ESCAPING_POLICY;
        recalculateAutoEscapingField();
    }
    children = MixedContentElements()
    end = <END_NOAUTOESC>
    {
        NoAutoEscBlock result = new NoAutoEscBlock(children);
        result.setLocation(template, start, end);
        
        autoEscapingPolicy = lastAutoEscapingPolicy;
        recalculateAutoEscapingField(); 
        return result;
    }
}

/**
 * Production to terminate potentially empty elements. Either a ">" or "/>"
 */
Token LooseDirectiveEnd() :
{
    Token t;
}
{
    (
        t = <DIRECTIVE_END>
        |
        t = <EMPTY_DIRECTIVE_END>
    )
    {
        return t;
    }
}

PropertySetting Setting() :
{
    Token start, end, key;
    Expression value;
}
{
    start = <SETTING>
    key = <ID>
    <EQUALS>
    value = Expression()
    end = LooseDirectiveEnd()
    {
        token_source.checkNamingConvention(key);
        PropertySetting result = new PropertySetting(key, token_source, value, template.getConfiguration());
        result.setLocation(template, start, end);
        return result;
    }
}

/**
 * A production for FreeMarker directives.
 */
TemplateElement FreemarkerDirective() :
{
    TemplateElement tp;
}
{
    // Note that this doesn't include elements like "else", "recover", etc., because those indicate the end
    // of the MixedContentElements of "if", "attempt", etc.
    (
        tp = If()
        |
        tp = List()
        |
        tp = ForEach()
        |
        tp = Assign()
        |
        tp = Include()
        |
        tp = Import()
        |
        tp = Macro()
        |
        tp = Compress()
        |
        tp = UnifiedMacroTransform()
        |
        tp = Items()
        |
        tp = Sep()
        |
        tp = Call()
        |
        tp = Comment()
        |
        tp = NoParse()
        |
        tp = Transform()
        |
        tp = Switch()
        |
        tp = Setting()
        |
        tp = Break()
        |
        tp = Continue()
        |
        tp = Return()
        |
        tp = Stop()
        |
        tp = Flush()
        |
        tp = Trim()
        |
        tp = Nested()
        |
        tp = Escape()
        |
        tp = NoEscape()
        |
        tp = Visit()
        |
        tp = Recurse()
        |
        tp = FallBack()
        |
        tp = Attempt()
        |
        tp = OutputFormat()
        |
        tp = AutoEsc()
        |
        tp = NoAutoEsc()
    )
    {
        return tp;
    }
}

/**
 * Production for a block of raw text
 * i.e. text that contains no
 * FreeMarker directives.
 */
TextBlock PCData() :
{
    StringBuilder buf = new StringBuilder();
    Token t = null, start = null, prevToken = null;
}
{
    (
        (
            t = <STATIC_TEXT_WS>
            |
            t = <STATIC_TEXT_NON_WS>
            |
            t = <STATIC_TEXT_FALSE_ALARM>
        )
        {
            buf.append(t.image);
            if (start == null) start = t;
            if (prevToken != null) prevToken.next = null;
            prevToken = t;
        }
    )+
    {
        if (stripText && mixedContentNesting == 1 && !preventStrippings) return null;

        TextBlock result = new TextBlock(buf.toString(), false);
        result.setLocation(template, start, t);
        return result;
    }
}

TextBlock WhitespaceText() :
{
    Token t = null, start = null;
}
{
    t = <STATIC_TEXT_WS>
    {
        if (stripText && mixedContentNesting == 1 && !preventStrippings) return null;

        TextBlock result = new TextBlock(t.image, false);
        result.setLocation(template, t, t);
        return result;
    }
}

/**
 * Production for dealing with unparsed content,
 * i.e. what is inside a comment or noparse tag.
 * It returns the ending token. The content
 * of the tag is put in buf.
 */
Token UnparsedContent(Token start, StringBuilder buf) :
{
    Token t;
}
{
    (
        (t = <KEEP_GOING> | t = <MAYBE_END> | t = <TERSE_COMMENT_END> | t = <LONE_LESS_THAN_OR_DASH>)
        {
            buf.append(t.image);
        }
    )+
    {
        buf.setLength(buf.length() - t.image.length());
        if (!t.image.endsWith(";")
                && _TemplateAPI.getTemplateLanguageVersionAsInt(template) >= _VersionInts.V_2_3_21) {
            throw new ParseException("Unclosed \"" + start.image + "\"", template, start);
        }
        return t;
    }
}

TemplateElements MixedContentElements() :
{
    TemplateElement[] childBuffer = null;
    int childCount = 0;
    TemplateElement elem;
    mixedContentNesting++;
}
{
    (
        LOOKAHEAD(1) // Just tells javacc that we know what we're doing.
        (
            elem = PCData()
            |
            elem = StringOutput()
            |
            elem = NumericalOutput()
            |
            elem = FreemarkerDirective()
        )
        {
            // Note: elem == null when it's was top-level PCData removed by stripText
            if (elem != null) {
	            childCount++;
	            if (childBuffer == null) {
	                childBuffer = new TemplateElement[16]; 
	            } else if (childBuffer.length < childCount) {
	                TemplateElement[] newChildBuffer = new TemplateElement[childCount * 2];
	                for (int i = 0; i < childBuffer.length; i++) {
	                    newChildBuffer[i] = childBuffer[i];
	                }
	                childBuffer = newChildBuffer;
	            }
	            childBuffer[childCount - 1] = elem;
            }
        }
    )*
    {
        mixedContentNesting--;
        return childBuffer != null ? new TemplateElements(childBuffer, childCount) : TemplateElements.EMPTY;
    }
}

/**
 * Not used anymore; kept for backward compatibility.
 *
 * @deprecated Use {@link #MixedContentElements} instead.
 */
MixedContent MixedContent() :
{
    MixedContent mixedContent = new MixedContent();
    TemplateElement elem, begin = null;
    mixedContentNesting++;
}
{
    (
        LOOKAHEAD(1) // Just tells javacc that we know what we're doing.
        (
            elem = PCData()
            |
            elem = StringOutput()
            |
            elem = NumericalOutput()
            |
            elem = FreemarkerDirective()
        )
        {
            if (begin == null) {
                begin = elem;
            }
            mixedContent.addElement(elem);
        }
    )+
    {
        mixedContentNesting--;
        mixedContent.setLocation(template, begin, elem);
        return mixedContent;
    }
}

/**
 * Not used anymore; kept for backward compatibility.
 *
 * <p>A production for a block of optional content.
 * Returns an empty Text block if there is no
 * content.
 *
 * @deprecated Use {@link #MixedContentElements} instead.
 */
TemplateElement OptionalBlock() :
{
    TemplateElement tp = null;
}
{
    [
        LOOKAHEAD(1) // has no effect but to get rid of a spurious warning.
        tp = MixedContent()
    ]
    {
        return tp != null ? tp : new TextBlock(CollectionUtils.EMPTY_CHAR_ARRAY, false);
    }
}

/**
 * A production freemarker text that may contain
 * ${...} and #{...} but no directives.
 */
TemplateElement FreeMarkerText() :
{
    MixedContent nodes = new MixedContent();
    TemplateElement elem, begin = null;
}
{
    (
        (
            elem = PCData()
            |
            elem = StringOutput()
            |
            elem = NumericalOutput()
        )
        {
            if (begin == null) {
            	begin = elem;
            }
            nodes.addChild(elem);
        }
    )+
    {
        nodes.setLocation(template, begin, elem);
        return nodes;
    }
}

/**
 * To be used between tags that in theory has nothing between, such between #switch and the first #case.
 */
MixedContent WhitespaceAndComments() :
{
    MixedContent nodes = new MixedContent();
    TemplateElement elem, begin = null;
}
{
    (
        (
            elem = WhitespaceText()
            |
            elem = Comment()
        )
        {
            if (elem != null) { // not removed by stripText
	            if (begin == null) {
	                begin = elem;
	            }
	            nodes.addChild(elem);
            }
        }
    )+
    {
        if (begin == null // Was is removed by stripText?
                // Nodes here won't be ever executed anyway, but whitespace stripping should still remove the
                // lonely TextBlock from the AST, as that's purely source code formatting. If it's not lonely, then
                // there must be a comment, in which case the generic whitespace stripping algorithm will kick in.
                || stripWhitespace && !preventStrippings
                        && nodes.getChildCount() == 1 && nodes.getChild(0) instanceof TextBlock) {
            return null;
        }
        nodes.setLocation(template, begin, elem);
        return nodes;
    }
}

void HeaderElement() :
{
    Token key;
    Expression exp = null;
    Token autoEscRequester = null;
}
{
    [<STATIC_TEXT_WS>]
    (
        <TRIVIAL_FTL_HEADER>
        |
        (
            <FTL_HEADER>
            (
                key = <ID>
                <EQUALS>
                exp = Expression()
                {
                    token_source.checkNamingConvention(key);
                
                    String ks = key.image;
                    TemplateModel value = null;
                    try {
                        value = exp.eval(null);
                    } catch (Exception e) {
                        throw new ParseException(
                        		"Could not evaluate expression (on parse-time): " + exp.getCanonicalForm()
                        		+ " \nUnderlying cause: " +  e,
                                exp, e);
                    }
                    String vs = null;
                    if (value instanceof TemplateScalarModel) {
                        try {
                            vs = ((TemplateScalarModel) exp).getAsString();
                        } catch (TemplateModelException tme) {}
                    }
                    if (template != null) {
                        if (ks.equalsIgnoreCase("encoding")) {
                            if (vs == null) {
                                throw new ParseException("Expected a string constant for \"" + ks + "\".", exp);
                            }
                            String encoding = template.getEncoding();
                            if (encoding != null && !encoding.equalsIgnoreCase(vs)) {
                                throw new Template.WrongEncodingException(vs, encoding);
                            }
                        } else if (ks.equalsIgnoreCase("STRIP_WHITESPACE") || ks.equals("stripWhitespace")) {
                            this.stripWhitespace = getBoolean(exp, true);
                        } else if (ks.equalsIgnoreCase("STRIP_TEXT") || ks.equals("stripText")) {
                            this.stripText = getBoolean(exp, true);
                        } else if (ks.equalsIgnoreCase("STRICT_SYNTAX") || ks.equals("strictSyntax")) {
                            this.token_source.strictSyntaxMode = getBoolean(exp, true);
                        } else if (ks.equalsIgnoreCase("auto_esc") || ks.equals("autoEsc")) {
                            if (getBoolean(exp, false)) {
                                autoEscRequester = key;
                                autoEscapingPolicy = Configuration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY;
                            } else {
                                if (autoEscapingPolicy == Configuration.FORCE_AUTO_ESCAPING_POLICY) {
                                    throw new ParseException(
                                            forcedAutoEscapingPolicyExceptionMessage("auto_esc setting"),
                                            exp);
                                }
                                autoEscapingPolicy = Configuration.DISABLE_AUTO_ESCAPING_POLICY;
                            }
                            recalculateAutoEscapingField();
                            _TemplateAPI.setAutoEscaping(template, autoEscaping);
                        } else if (ks.equalsIgnoreCase("output_format") || ks.equals("outputFormat")) {
                            if (vs == null) {
                                throw new ParseException("Expected a string constant for \"" + ks + "\".", exp);
                            }
                            try {
                                outputFormat = template.getConfiguration().getOutputFormat(vs);
					        } catch (IllegalArgumentException e) {
					            throw new ParseException("Invalid format name: " + e.getMessage(), exp, e.getCause());
					        } catch (UnregisteredOutputFormatException e) {
					            throw new ParseException(e.getMessage(), exp, e.getCause());
					        }
                            recalculateAutoEscapingField();                                
                            _TemplateAPI.setOutputFormat(template, outputFormat);
                            _TemplateAPI.setAutoEscaping(template, autoEscaping);
                        } else if (ks.equalsIgnoreCase("ns_prefixes") || ks.equals("nsPrefixes")) {
                            if (!(value instanceof TemplateHashModelEx)) {
                                throw new ParseException("Expecting a hash of prefixes to namespace URI's.", exp);
                            }
                            TemplateHashModelEx prefixMap = (TemplateHashModelEx) value;
                            try {
                                TemplateCollectionModel keys = prefixMap.keys();
                                for (TemplateModelIterator it = keys.iterator(); it.hasNext();) {
                                    String prefix = ((TemplateScalarModel) it.next()).getAsString();
                                    TemplateModel valueModel = prefixMap.get(prefix);
                                    if (!(valueModel instanceof TemplateScalarModel)) {
                                        throw new ParseException("Non-string value in prefix to namespace hash.", exp);
                                    }
                                    String nsURI = ((TemplateScalarModel) valueModel).getAsString();
                                    try {
                                        template.addPrefixNSMapping(prefix, nsURI);
                                    } catch (IllegalArgumentException iae) {
                                        throw new ParseException(iae.getMessage(), exp);
                                    }
                                }
                            } catch (TemplateModelException tme) {
                            }
                        } else if (ks.equalsIgnoreCase("attributes")) {
                            if (!(value instanceof TemplateHashModelEx)) {
                                throw new ParseException("Expecting a hash of attribute names to values.", exp);
                            }
                            TemplateHashModelEx attributeMap = (TemplateHashModelEx) value;
                            try {
                                TemplateCollectionModel keys = attributeMap.keys();
                                for (TemplateModelIterator it = keys.iterator(); it.hasNext();) {
                                        String attName = ((TemplateScalarModel) it.next()).getAsString();
                                        Object attValue = DeepUnwrap.unwrap(attributeMap.get(attName));
                                        template.setCustomAttribute(attName, attValue);
                                }
                            } catch (TemplateModelException tme) {
                            }
                        } else {
                            String correctName;
	                        if (ks.equals("charset")) {
	                            correctName = "encoding";
	                        } else if (ks.equals("xmlns")) {
	                            // [2.4] If camel case will be the default, update this
                                correctName
                                        = token_source.namingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION
                                                ? "nsPrefixes" : "ns_prefixes";
                            } else if (ks.equals("auto_escape") || ks.equals("auto_escaping") || ks.equals("autoesc")) {
                                correctName = "auto_esc";
                            } else if (ks.equals("autoEscape") || ks.equals("autoEscaping")) {
                                correctName = "autoEsc";
	                        } else {
                                correctName = null;
	                        }
                            throw new ParseException(
                                    "Unknown FTL header parameter: " + key.image
                                    + (correctName == null ? "" : ". You may meant: " + correctName),
                                    template, key);
                        }
                    }
                }
            )*
        )
        {
            if (autoEscRequester != null) {
                checkCurrentOutputFormatCanEscape(autoEscRequester);
            }        
        }
        LooseDirectiveEnd()
    )
}

Map ParamList() :
{
    Identifier id;
    Expression exp;
    Map result = new HashMap();
}
{
    (
        id = Identifier()
        <EQUALS>
        exp = Expression() { result.put(id.toString(), exp); }
        [<COMMA>]
    )+
    {
        return result;
    }
}

/**
 * Parses the already un-escaped content of a string literal (input must not include the quotation marks).
 *
 * @return A {@link List} of {@link String}-s and {@link Interpolation}-s. 
 */
List<Object> StaticTextAndInterpolations() :
{
    Token t;
    Interpolation interpolation;
    StringBuilder staticTextCollector = null;
    ArrayList<Object> parts = new ArrayList<Object>();
}
{
    (
	    (
		    t = <STATIC_TEXT_WS>
		    |
		    t = <STATIC_TEXT_NON_WS>
		    |
		    t = <STATIC_TEXT_FALSE_ALARM>
	    )
	    {
	       String s = t.image;
	       if (s.length() != 0) {
	           if (staticTextCollector == null) {
	               staticTextCollector = new StringBuilder(t.image);
	           } else {
	               staticTextCollector.append(t.image);
	           }
	       }
	    }
	    |
	    (
	        LOOKAHEAD(<DOLLAR_INTERPOLATION_OPENING>|<SQUARE_BRACKET_INTERPOLATION_OPENING>)
		    (
		        interpolation = StringOutput()
	        )
		    |
            LOOKAHEAD(<HASH_INTERPOLATION_OPENING>)
		    (
                interpolation = NumericalOutput()
		    )
	    )
	    {
            if (staticTextCollector != null) {
                parts.add(staticTextCollector.toString());
                staticTextCollector.setLength(0);
            }
            parts.add(interpolation);
	    }
    )*
    {
        if (staticTextCollector != null && staticTextCollector.length() != 0) {
            parts.add(staticTextCollector.toString());
        }
        parts.trimToSize();
        return parts;
    }
}

/**
 * Root production to be used when parsing
 * an entire file.
 */
TemplateElement Root() :
{
    TemplateElements children;
}
{
    [
        LOOKAHEAD([<STATIC_TEXT_WS>](<TRIVIAL_FTL_HEADER>|<FTL_HEADER>))
        HeaderElement()
    ]
    {
        if (!(outputFormat instanceof MarkupOutputFormat) && autoEscapingPolicy == Configuration.FORCE_AUTO_ESCAPING_POLICY) {
            throw new IllegalArgumentException(forcedAutoEscapingPolicyExceptionMessage(outputFormat));
        }
    }
    children = MixedContentElements()
    <EOF>
    {
        TemplateElement root = children.asSingleElement(); 
        root.setFieldsForRootElement();
        if (!preventStrippings) {
            root = root.postParseCleanup(stripWhitespace);
        }
        // The cleanup result is possibly an element from deeper:
        root.setFieldsForRootElement();
        return root;
    }
}
