/*
 * 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;
            }
        }
        if (!(outputFormat instanceof MarkupOutputFormat) && autoEscapingPolicy == Configuration.FORCE_AUTO_ESCAPING_POLICY) {
            throw new IllegalArgumentException(forcedAutoEscapingPolicyExceptionMessage(outputFormat));
        }
        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()
    ]
    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;
    }
}
