http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ReturnInstruction.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/ast/ReturnInstruction.java 
b/src/main/java/org/apache/freemarker/core/ast/ReturnInstruction.java
deleted file mode 100644
index 5b93f41..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/ReturnInstruction.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * Represents a <return> instruction to jump out of a macro.
- */
-public final class ReturnInstruction extends TemplateElement {
-
-    private Expression exp;
-
-    ReturnInstruction(Expression exp) {
-        this.exp = exp;
-    }
-
-    @Override
-    TemplateElement[] accept(Environment env) throws TemplateException {
-        if (exp != null) {
-            env.setLastReturnValue(exp.eval(env));
-        }
-        if (nextSibling() == null && getParentElement() instanceof Macro) {
-            // Avoid unnecessary exception throwing 
-            return null;
-        }
-        throw Return.INSTANCE;
-    }
-
-    @Override
-    protected String dump(boolean canonical) {
-        StringBuilder sb = new StringBuilder();
-        if (canonical) sb.append('<');
-        sb.append(getNodeTypeSymbol());
-        if (exp != null) {
-            sb.append(' ');
-            sb.append(exp.getCanonicalForm());
-        }
-        if (canonical) sb.append("/>");
-        return sb.toString();
-    }
-
-    @Override
-    String getNodeTypeSymbol() {
-        return "#return";
-    }
-    
-    public static class Return extends RuntimeException {
-        static final Return INSTANCE = new Return();
-        private Return() {
-        }
-    }
-    
-    @Override
-    int getParameterCount() {
-        return 1;
-    }
-
-    @Override
-    Object getParameterValue(int idx) {
-        if (idx != 0) throw new IndexOutOfBoundsException();
-        return exp;
-    }
-
-    @Override
-    ParameterRole getParameterRole(int idx) {
-        if (idx != 0) throw new IndexOutOfBoundsException();
-        return ParameterRole.VALUE;
-    }
-
-    @Override
-    boolean isNestedBlockRepeater() {
-        return false;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/RightUnboundedRangeModel.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/ast/RightUnboundedRangeModel.java 
b/src/main/java/org/apache/freemarker/core/ast/RightUnboundedRangeModel.java
deleted file mode 100644
index 3cde385..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/RightUnboundedRangeModel.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-abstract class RightUnboundedRangeModel extends RangeModel {
-    
-    RightUnboundedRangeModel(int begin) {
-        super(begin);
-    }
-
-    @Override
-    final int getStep() {
-        return 1;
-    }
-
-    @Override
-    final boolean isRightUnbounded() {
-        return true;
-    }
-    
-    @Override
-    final boolean isRightAdaptive() {
-        return true;
-    }
-
-    @Override
-    final boolean isAffactedByStringSlicingBug() {
-        return false;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/Sep.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/Sep.java 
b/src/main/java/org/apache/freemarker/core/ast/Sep.java
deleted file mode 100644
index 4a91bb8..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/Sep.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.
- */
-package org.apache.freemarker.core.ast;
-
-import java.io.IOException;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.ast.IteratorBlock.IterationContext;
-
-/**
- * A #sep element.
- */
-class Sep extends TemplateElement {
-
-    public Sep(TemplateElements children) {
-        setChildren(children);
-    }
-
-    @Override
-    TemplateElement[] accept(Environment env) throws TemplateException, 
IOException {
-        final IterationContext iterCtx = 
IteratorBlock.findEnclosingIterationContext(env, null);
-        if (iterCtx == null) {
-            // The parser should prevent this situation
-            throw new _MiscTemplateException(env,
-                    getNodeTypeSymbol(), " without iteration in context");
-        }
-        
-        if (iterCtx.hasNext()) {
-            return getChildBuffer();
-        }
-        return null;
-    }
-
-    @Override
-    boolean isNestedBlockRepeater() {
-        return false;
-    }
-
-    @Override
-    protected String dump(boolean canonical) {
-        StringBuilder sb = new StringBuilder();
-        if (canonical) sb.append('<');
-        sb.append(getNodeTypeSymbol());
-        if (canonical) {
-            sb.append('>');
-            sb.append(getChildrenCanonicalForm());
-            sb.append("</");
-            sb.append(getNodeTypeSymbol());
-            sb.append('>');
-        }
-        return sb.toString();
-    }
-
-    @Override
-    String getNodeTypeSymbol() {
-        return "#sep";
-    }
-
-    @Override
-    int getParameterCount() {
-        return 0;
-    }
-
-    @Override
-    Object getParameterValue(int idx) {
-        throw new IndexOutOfBoundsException();
-    }
-
-    @Override
-    ParameterRole getParameterRole(int idx) {
-        throw new IndexOutOfBoundsException();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/SpecialBuiltIn.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/SpecialBuiltIn.java 
b/src/main/java/org/apache/freemarker/core/ast/SpecialBuiltIn.java
deleted file mode 100644
index 2565cf7..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/SpecialBuiltIn.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-package org.apache.freemarker.core.ast;
-
-
-/**
- * Marker class for built-ins that has special treatment during parsing.
- */
-abstract class SpecialBuiltIn extends BuiltIn {
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/StopException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/StopException.java 
b/src/main/java/org/apache/freemarker/core/ast/StopException.java
deleted file mode 100644
index 9b135f1..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/StopException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * This exception is thrown when a <tt>#stop</tt> directive is encountered. 
- */
-public class StopException extends TemplateException {
-    
-    StopException(Environment env) {
-        super(env);
-    }
-
-    StopException(Environment env, String s) {
-        super(s, env);
-    }
-
-    @Override
-    public void printStackTrace(PrintWriter pw) {
-        synchronized (pw) {
-            String msg = getMessage();
-            pw.print("Encountered stop instruction");
-            if (msg != null && !msg.equals("")) {
-                pw.println("\nCause given: " + msg);
-            } else pw.println();
-            super.printStackTrace(pw);
-        }
-    }
-
-    @Override
-    public void printStackTrace(PrintStream ps) {
-        synchronized (ps) {
-            String msg = getMessage();
-            ps.print("Encountered stop instruction");
-            if (msg != null && !msg.equals("")) {
-                ps.println("\nCause given: " + msg);
-            } else ps.println();
-            super.printStackTrace(ps);
-        }
-    }
-    
-}
-
-

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/StopInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/StopInstruction.java 
b/src/main/java/org/apache/freemarker/core/ast/StopInstruction.java
deleted file mode 100644
index 24f466f..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/StopInstruction.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * Represents a &lt;stop&gt; instruction to abort template processing.
- */
-final class StopInstruction extends TemplateElement {
-
-    private Expression exp;
-
-    StopInstruction(Expression exp) {
-        this.exp = exp;
-    }
-
-    @Override
-    TemplateElement[] accept(Environment env) throws TemplateException {
-        if (exp == null) {
-            throw new StopException(env);
-        }
-        throw new StopException(env, exp.evalAndCoerceToPlainText(env));
-    }
-
-    @Override
-    protected String dump(boolean canonical) {
-        StringBuilder sb = new StringBuilder();
-        if (canonical) sb.append('<');
-        sb.append(getNodeTypeSymbol());
-        if (exp != null) {
-            sb.append(' ');
-            sb.append(exp.getCanonicalForm());
-        }
-        if (canonical) sb.append("/>");
-        return sb.toString();
-    }
-    
-    @Override
-    String getNodeTypeSymbol() {
-        return "#stop";
-    }
-    
-    @Override
-    int getParameterCount() {
-        return 1;
-    }
-
-    @Override
-    Object getParameterValue(int idx) {
-        if (idx != 0) throw new IndexOutOfBoundsException();
-        return exp;
-    }
-
-    @Override
-    ParameterRole getParameterRole(int idx) {
-        if (idx != 0) throw new IndexOutOfBoundsException();
-        return ParameterRole.MESSAGE;
-    }
-
-    @Override
-    boolean isNestedBlockRepeater() {
-        return false;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/StringArraySequence.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/ast/StringArraySequence.java 
b/src/main/java/org/apache/freemarker/core/ast/StringArraySequence.java
deleted file mode 100644
index 895b31a..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/StringArraySequence.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.TemplateSequenceModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-/**
- * Sequence variable implementation that wraps a String[] with relatively low
- * resource utilization. Warning: it does not copy the wrapped array, so do
- * not modify that after the model was made!
- */
-public class StringArraySequence implements TemplateSequenceModel {
-    private String[] stringArray;
-    private TemplateScalarModel[] array;
-
-    /**
-     * Warning: Does not copy the argument array!
-     */
-    public StringArraySequence(String[] stringArray) {
-        this.stringArray = stringArray;
-    }
-
-    @Override
-    public TemplateModel get(int index) {
-        if (array == null) {
-            array = new TemplateScalarModel[stringArray.length];
-        }
-        TemplateScalarModel result = array[index];
-        if (result == null) {
-            result = new SimpleScalar(stringArray[index]);
-            array[index] = result;
-        }
-        return result;
-    }
-
-    @Override
-    public int size() {
-        return stringArray.length;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/StringLiteral.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/StringLiteral.java 
b/src/main/java/org/apache/freemarker/core/ast/StringLiteral.java
deleted file mode 100644
index 3d9ea96..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/StringLiteral.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-import java.io.StringReader;
-import java.util.List;
-
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-import org.apache.freemarker.core.util.FTLUtil;
-
-final class StringLiteral extends Expression implements TemplateScalarModel {
-    
-    private final String value;
-    
-    /** {@link List} of {@link String}-s and {@link Interpolation}-s. */
-    private List<Object> dynamicValue;
-    
-    StringLiteral(String value) {
-        this.value = value;
-    }
-    
-    /**
-     * @param parentTkMan
-     *            The token source of the template that contains this string 
literal. As of this writing, we only need
-     *            this to share the {@code namingConvetion} with that.
-     */
-    void parseValue(FMParserTokenManager parentTkMan, OutputFormat 
outputFormat) throws ParseException {
-        // The way this works is incorrect (the literal should be parsed 
without un-escaping),
-        // but we can't fix this backward compatibly.
-        if (value.length() > 3 && (value.indexOf("${") >= 0 || 
value.indexOf("#{") >= 0)) {
-            
-            Template parentTemplate = getTemplate();
-            ParserConfiguration pcfg = parentTemplate.getParserConfiguration();
-
-            try {
-                SimpleCharStream simpleCharacterStream = new SimpleCharStream(
-                        new StringReader(value),
-                        beginLine, beginColumn + 1,
-                        value.length());
-                simpleCharacterStream.setTabSize(pcfg.getTabSize());
-                
-                FMParserTokenManager tkMan = new FMParserTokenManager(
-                        simpleCharacterStream);
-                
-                FMParser parser = new FMParser(parentTemplate, false, tkMan, 
pcfg,
-                        TemplateSpecifiedEncodingHandler.DEFAULT);
-                // We continue from the parent parser's current state:
-                parser.setupStringLiteralMode(parentTkMan, outputFormat);
-                try {
-                    dynamicValue = parser.StaticTextAndInterpolations();
-                } finally {
-                    // The parent parser continues from this parser's current 
state:
-                    parser.tearDownStringLiteralMode(parentTkMan);
-                }
-            } catch (ParseException e) {
-                e.setTemplateName(parentTemplate.getSourceName());
-                throw e;
-            }
-            constantValue = null;
-        }
-    }
-    
-    @Override
-    TemplateModel _eval(Environment env) throws TemplateException {
-        if (dynamicValue == null) {
-            return new SimpleScalar(value);
-        } else {
-            // This should behave like concatenating the values with `+`. 
Thus, an interpolated expression that
-            // returns markup promotes the result of the whole expression to 
markup.
-            
-            // Exactly one of these is non-null, depending on if the result 
will be plain text or markup, which can
-            // change during evaluation, depending on the result of the 
interpolations:
-            StringBuilder plainTextResult = null;
-            TemplateMarkupOutputModel<?> markupResult = null;
-            
-            for (Object part : dynamicValue) {
-                Object calcedPart =
-                        part instanceof String ? part
-                        : ((Interpolation) 
part).calculateInterpolatedStringOrMarkup(env);
-                if (markupResult != null) {
-                    TemplateMarkupOutputModel<?> partMO = calcedPart 
instanceof String
-                            ? 
markupResult.getOutputFormat().fromPlainTextByEscaping((String) calcedPart)
-                            : (TemplateMarkupOutputModel<?>) calcedPart;
-                    markupResult = EvalUtil.concatMarkupOutputs(this, 
markupResult, partMO);
-                } else { // We are using `plainTextOutput` (or nothing yet)
-                    if (calcedPart instanceof String) {
-                        String partStr = (String) calcedPart;
-                        if (plainTextResult == null) {
-                            plainTextResult = new StringBuilder(partStr);
-                        } else {
-                            plainTextResult.append(partStr);
-                        }
-                    } else { // `calcedPart` is TemplateMarkupOutputModel
-                        TemplateMarkupOutputModel<?> moPart = 
(TemplateMarkupOutputModel<?>) calcedPart;
-                        if (plainTextResult != null) {
-                            TemplateMarkupOutputModel<?> leftHandMO = 
moPart.getOutputFormat()
-                                    
.fromPlainTextByEscaping(plainTextResult.toString());
-                            markupResult = EvalUtil.concatMarkupOutputs(this, 
leftHandMO, moPart);
-                            plainTextResult = null;
-                        } else {
-                            markupResult = moPart;
-                        }
-                    }
-                }
-            } // for each part
-            return markupResult != null ? markupResult
-                    : plainTextResult != null ? new 
SimpleScalar(plainTextResult.toString())
-                    : SimpleScalar.EMPTY_STRING;
-        }
-    }
-
-    @Override
-    public String getAsString() {
-        return value;
-    }
-    
-    /**
-     * Tells if this is something like <tt>"${foo}"</tt>, which is usually a 
user mistake.
-     */
-    boolean isSingleInterpolationLiteral() {
-        return dynamicValue != null && dynamicValue.size() == 1
-                && dynamicValue.get(0) instanceof Interpolation;
-    }
-    
-    @Override
-    public String getCanonicalForm() {
-        if (dynamicValue == null) {
-            return FTLUtil.toStringLiteral(value);
-        } else {
-            StringBuilder sb = new StringBuilder();
-            sb.append('"');
-            for (Object child : dynamicValue) {
-                if (child instanceof Interpolation) {
-                    sb.append(((Interpolation) 
child).getCanonicalFormInStringLiteral());
-                } else {
-                    sb.append(FTLUtil.escapeStringLiteralPart((String) child, 
'"'));
-                }
-            }
-            sb.append('"');
-            return sb.toString();
-        }
-    }
-    
-    @Override
-    String getNodeTypeSymbol() {
-        return dynamicValue == null ? getCanonicalForm() : "dynamic \"...\"";
-    }
-    
-    @Override
-    boolean isLiteral() {
-        return dynamicValue == null;
-    }
-
-    @Override
-    protected Expression deepCloneWithIdentifierReplaced_inner(
-            String replacedIdentifier, Expression replacement, 
ReplacemenetState replacementState) {
-        StringLiteral cloned = new StringLiteral(value);
-        // FIXME: replacedIdentifier should be searched inside 
interpolatedOutput too:
-        cloned.dynamicValue = dynamicValue;
-        return cloned;
-    }
-
-    @Override
-    int getParameterCount() {
-        return dynamicValue == null ? 0 : dynamicValue.size();
-    }
-
-    @Override
-    Object getParameterValue(int idx) {
-        checkIndex(idx);
-        return dynamicValue.get(idx);
-    }
-
-    private void checkIndex(int idx) {
-        if (dynamicValue == null || idx >= dynamicValue.size()) {
-            throw new IndexOutOfBoundsException();
-        }
-    }
-
-    @Override
-    ParameterRole getParameterRole(int idx) {
-        checkIndex(idx);
-        return ParameterRole.VALUE_PART;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/SwitchBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/SwitchBlock.java 
b/src/main/java/org/apache/freemarker/core/ast/SwitchBlock.java
deleted file mode 100644
index e320d14..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/SwitchBlock.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-import java.io.IOException;
-
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * An instruction representing a switch-case structure.
- */
-final class SwitchBlock extends TemplateElement {
-
-    private Case defaultCase;
-    private final Expression searched;
-
-    /**
-     * @param searched the expression to be tested.
-     */
-    SwitchBlock(Expression searched) {
-        this.searched = searched;
-        setChildBufferCapacity(4);
-    }
-
-    /**
-     * @param cas a Case element.
-     */
-    void addCase(Case cas) {
-        if (cas.condition == null) {
-            defaultCase = cas;
-        }
-        addChild(cas);
-    }
-
-    @Override
-    TemplateElement[] accept(Environment env)
-        throws TemplateException, IOException {
-        boolean processedCase = false;
-        int ln = getChildCount();
-        try {
-            for (int i = 0; i < ln; i++) {
-                Case cas = (Case) getChild(i);
-                boolean processCase = false;
-
-                // Fall through if a previous case tested true.
-                if (processedCase) {
-                    processCase = true;
-                } else if (cas.condition != null) {
-                    // Otherwise, if this case isn't the default, test it.
-                    processCase = EvalUtil.compare(
-                            searched,
-                            EvalUtil.CMP_OP_EQUALS, "case==", cas.condition, 
cas.condition, env);
-                }
-                if (processCase) {
-                    env.visit(cas);
-                    processedCase = true;
-                }
-            }
-
-            // If we didn't process any nestedElements, and we have a default,
-            // process it.
-            if (!processedCase && defaultCase != null) {
-                env.visit(defaultCase);
-            }
-        } catch (BreakInstruction.Break br) {}
-        return null;
-    }
-
-    @Override
-    protected String dump(boolean canonical) {
-        StringBuilder buf = new StringBuilder();
-        if (canonical) buf.append('<');
-        buf.append(getNodeTypeSymbol());
-        buf.append(' ');
-        buf.append(searched.getCanonicalForm());
-        if (canonical) {
-            buf.append('>');
-            int ln = getChildCount();
-            for (int i = 0; i < ln; i++) {
-                Case cas = (Case) getChild(i);
-                buf.append(cas.getCanonicalForm());
-            }
-            buf.append("</").append(getNodeTypeSymbol()).append('>');
-        }
-        return buf.toString();
-    }
-
-    @Override
-    String getNodeTypeSymbol() {
-        return "#switch";
-    }
-
-    @Override
-    int getParameterCount() {
-        return 1;
-    }
-
-    @Override
-    Object getParameterValue(int idx) {
-        if (idx != 0) throw new IndexOutOfBoundsException();
-        return searched;
-    }
-
-    @Override
-    ParameterRole getParameterRole(int idx) {
-        if (idx != 0) throw new IndexOutOfBoundsException();
-        return ParameterRole.VALUE;
-    }
-
-    @Override
-    boolean isNestedBlockRepeater() {
-        return false;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/TemplateClassResolver.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/ast/TemplateClassResolver.java 
b/src/main/java/org/apache/freemarker/core/ast/TemplateClassResolver.java
deleted file mode 100644
index 3b354d3..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/TemplateClassResolver.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.util._ClassUtil;
-
-/**
- * Used by built-ins and other template language features that get a class
- * based on a string. This can be handy both for implementing security
- * restrictions and for working around local class-loader issues. 
- * 
- * The implementation should be thread-safe, unless an
- * instance is always only used in a single {@link Environment} object.
- * 
- * @see Configurable#setNewBuiltinClassResolver(TemplateClassResolver)
- * 
- * @since 2.3.17
- */
-public interface TemplateClassResolver {
-    
-    /**
-     * Simply calls {@link _ClassUtil#forName(String)}.
-     */
-    TemplateClassResolver UNRESTRICTED_RESOLVER = new TemplateClassResolver() {
-
-        @Override
-        public Class resolve(String className, Environment env, Template 
template)
-        throws TemplateException {
-            try {
-                return _ClassUtil.forName(className);
-            } catch (ClassNotFoundException e) {
-                throw new _MiscTemplateException(e, env);
-            }
-        }
-        
-    };
-    
-    /**
-     * Doesn't allow resolving any classes.
-     */
-    TemplateClassResolver ALLOWS_NOTHING_RESOLVER =  new 
TemplateClassResolver() {
-
-        @Override
-        public Class resolve(String className, Environment env, Template 
template)
-        throws TemplateException {
-            throw 
MessageUtil.newInstantiatingClassNotAllowedException(className, env);
-        }
-        
-    };
-
-    /**
-     * Gets a {@link Class} based on the class name.
-     * 
-     * @param className the full-qualified class name
-     * @param env the environment in which the template executes
-     * @param template the template where the operation that require the
-     *        class resolution resides in. This is <code>null</code> if the
-     *        call doesn't come from a template.
-     *        
-     * @throws TemplateException if the class can't be found or shouldn't be
-     *   accessed from a template for security reasons.
-     */
-    Class resolve(String className, Environment env, Template template) throws 
TemplateException;
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/TemplateCombinedMarkupOutputModel.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/ast/TemplateCombinedMarkupOutputModel.java
 
b/src/main/java/org/apache/freemarker/core/ast/TemplateCombinedMarkupOutputModel.java
deleted file mode 100644
index 5207b5a..0000000
--- 
a/src/main/java/org/apache/freemarker/core/ast/TemplateCombinedMarkupOutputModel.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- */
-package org.apache.freemarker.core.ast;
-
-/**
- * Stores combined markup to be printed; used with {@link 
CombinedMarkupOutputFormat}.
- * 
- * @since 2.3.24
- */
-public final class TemplateCombinedMarkupOutputModel
-        extends 
CommonTemplateMarkupOutputModel<TemplateCombinedMarkupOutputModel> {
-    
-    private final CombinedMarkupOutputFormat outputFormat;
-    
-    /**
-     * See {@link 
CommonTemplateMarkupOutputModel#CommonTemplateMarkupOutputModel(String, 
String)}.
-     * 
-     * @param outputFormat
-     *            The {@link CombinedMarkupOutputFormat} format this value is 
bound to. Because
-     *            {@link CombinedMarkupOutputFormat} has no singleton, we have 
to pass it in, unlike with most other
-     *            {@link CommonTemplateMarkupOutputModel}-s.
-     */
-    TemplateCombinedMarkupOutputModel(String plainTextContent, String 
markupContent,
-            CombinedMarkupOutputFormat outputFormat) {
-        super(plainTextContent, markupContent);
-        this.outputFormat = outputFormat; 
-    }
-
-    @Override
-    public CombinedMarkupOutputFormat getOutputFormat() {
-        return outputFormat;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/TemplateConfiguration.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/ast/TemplateConfiguration.java 
b/src/main/java/org/apache/freemarker/core/ast/TemplateConfiguration.java
deleted file mode 100644
index 21e5e50..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/TemplateConfiguration.java
+++ /dev/null
@@ -1,926 +0,0 @@
-/*
- * 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.
- */
-package org.apache.freemarker.core.ast;
-
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.TemplateExceptionHandler;
-import org.apache.freemarker.core.Version;
-import org.apache.freemarker.core._TemplateAPI;
-import org.apache.freemarker.core.model.ObjectWrapper;
-import 
org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver;
-import org.apache.freemarker.core.util._NullArgumentException;
-
-/**
- * Used for customizing the configuration settings for individual {@link 
Template}-s (or rather groups of templates),
- * relatively to the common setting values coming from the {@link 
Configuration}. This was designed with the standard
- * template loading mechanism of FreeMarker in mind ({@link 
Configuration#getTemplate(String)}
- * and {@link DefaultTemplateResolver}), though can also be reused for custom 
template loading and caching solutions.
- * 
- * <p>
- * Note on the {@code locale} setting: When used with the standard template 
loading/caching mechanism (
- * {@link Configuration#getTemplate(String)} and its overloads), localized 
lookup happens before the {@code locale}
- * specified here could have effect. The {@code locale} will be only set in 
the template that the localized lookup has
- * already found.
- * 
- * <p>
- * Note on the encoding setting {@code encoding}: See {@link 
#setEncoding(String)}.
- * 
- * <p>
- * Note that the result value of the reader methods (getter and "is" methods) 
is usually not useful unless the value of
- * that setting was already set on this object. Otherwise you will get the 
value from the parent {@link Configuration},
- * or an {@link IllegalStateException} before this object is associated to a 
{@link Configuration}.
- * 
- * <p>
- * If you are using this class for your own template loading and caching 
solution, rather than with the standard one,
- * you should be aware of a few more details:
- * 
- * <ul>
- * <li>This class implements both {@link Configurable} and {@link 
ParserConfiguration}. This means that it can influence
- * both the template parsing phase and the runtime settings. For both aspects 
(i.e., {@link ParserConfiguration} and
- * {@link Configurable}) to take effect, you have first pass this object to 
the {@link Template} constructor
- * (this is where the {@link ParserConfiguration} interface is used), and then 
you have to call {@link #apply(Template)}
- * on the resulting {@link Template} object (this is where the {@link 
Configurable} aspect is used).
- * 
- * <li>{@link #apply(Template)} only change the settings that weren't yet set 
on the {@link Template} (but are inherited
- * from the {@link Configuration}). This is primarily because if the template 
configures itself via the {@code #ftl}
- * header, those values should have precedence. A consequence of this is that 
if you want to configure the same
- * {@link Template} with multiple {@link TemplateConfiguration}-s, you either 
should merge them to a single one before
- * that (with {@link #merge(TemplateConfiguration)}), or you have to apply 
them in reverse order of their intended
- * precedence.
- * </ul>
- * 
- * @see Template#Template(String, String, Reader, Configuration, 
ParserConfiguration, String)
- * 
- * @since 2.3.24
- */
-public final class TemplateConfiguration extends Configurable implements 
ParserConfiguration {
-
-    private Integer tagSyntax;
-    private Integer namingConvention;
-    private Boolean whitespaceStripping;
-    private Integer autoEscapingPolicy;
-    private Boolean recognizeStandardFileExtensions;
-    private OutputFormat outputFormat;
-    private String encoding;
-    private Integer tabSize;
-
-    /**
-     * Creates a new instance. The parent will be {@code null} initially, but 
it will
-     * be changed to the real parent {@link Configuration} when this object is 
added to the {@link Configuration}. (It's
-     * not allowed to add the same instance to multiple {@link 
Configuration}-s).
-     */
-    public TemplateConfiguration() {
-        super((Configuration) null);
-    }
-
-    /**
-     * Same as {@link #setParentConfiguration(Configuration)}.
-     */
-    @Override
-    void setParent(Configurable cfg) {
-        _NullArgumentException.check("cfg", cfg);
-        if (!(cfg instanceof Configuration)) {
-            throw new IllegalArgumentException("The parent of a 
TemplateConfiguration can only be a Configuration");
-        }
-        
-        Configurable parent = getParent();
-        if (parent != null) {
-            if (parent != cfg) {
-                throw new IllegalStateException(
-                        "This TemplateConfiguration is already associated with 
a different Configuration instance.");
-            }
-            return;
-        }
-        
-        super.setParent(cfg);
-    }
-
-    /**
-     * Associates this instance with a {@link Configuration}; usually you 
don't call this, as it's called internally
-     * when this instance is added to a {@link Configuration}. This method can 
be called only once (except with the same
-     * {@link Configuration} parameter again, as that changes nothing anyway).
-     * 
-     * @throws IllegalArgumentException
-     *             if the argument is {@code null} or not a {@link 
Configuration}
-     * @throws IllegalStateException
-     *             if this object is already associated to a different {@link 
Configuration} object,
-     *             or if the {@code Configuration} has {@code 
#getIncompatibleImprovements()} less than 2.3.22 and
-     *             this object tries to change any non-parser settings  
-     */
-    public void setParentConfiguration(Configuration cfg) {
-        setParent(cfg);
-    }
-
-    /**
-     * Returns the parent {@link Configuration}, or {@code null} if none was 
associated yet.
-     */
-    public Configuration getParentConfiguration() {
-        return (Configuration) getParent();
-    }
-
-    private Configuration getNonNullParentConfiguration() {
-        Configurable parent = getParent();
-        if (parent == null) {
-            throw new IllegalStateException("The TemplateConfiguration wasn't 
associated with a Configuration yet.");
-        }
-        return (Configuration) parent;
-    }
-    
-    /**
-     * Set all settings in this {@link TemplateConfiguration} that were set in 
the parameter
-     * {@link TemplateConfiguration}, possibly overwriting the earlier value 
in this object. (A setting is said to be
-     * set in a {@link TemplateConfiguration} if it was explicitly set via a 
setter method, as opposed to be inherited.)
-     */
-    public void merge(TemplateConfiguration tc) {
-        if (tc.isAPIBuiltinEnabledSet()) {
-            setAPIBuiltinEnabled(tc.isAPIBuiltinEnabled());
-        }
-        if (tc.isArithmeticEngineSet()) {
-            setArithmeticEngine(tc.getArithmeticEngine());
-        }
-        if (tc.isAutoEscapingPolicySet()) {
-            setAutoEscapingPolicy(tc.getAutoEscapingPolicy());
-        }
-        if (tc.isAutoFlushSet()) {
-            setAutoFlush(tc.getAutoFlush());
-        }
-        if (tc.isBooleanFormatSet()) {
-            setBooleanFormat(tc.getBooleanFormat());
-        }
-        if (tc.isCustomDateFormatsSet()) {
-            setCustomDateFormats(mergeMaps(
-                    isCustomDateFormatsSet() ? getCustomDateFormats() : null, 
tc.getCustomDateFormats(), false));
-        }
-        if (tc.isCustomNumberFormatsSet()) {
-            setCustomNumberFormats(mergeMaps(
-                    isCustomNumberFormatsSet() ? getCustomNumberFormats() : 
null, tc.getCustomNumberFormats(), false));
-        }
-        if (tc.isDateFormatSet()) {
-            setDateFormat(tc.getDateFormat());
-        }
-        if (tc.isDateTimeFormatSet()) {
-            setDateTimeFormat(tc.getDateTimeFormat());
-        }
-        if (tc.isEncodingSet()) {
-            setEncoding(tc.getEncoding());
-        }
-        if (tc.isLocaleSet()) {
-            setLocale(tc.getLocale());
-        }
-        if (tc.isLogTemplateExceptionsSet()) {
-            setLogTemplateExceptions(tc.getLogTemplateExceptions());
-        }
-        if (tc.isNamingConventionSet()) {
-            setNamingConvention(tc.getNamingConvention());
-        }
-        if (tc.isNewBuiltinClassResolverSet()) {
-            setNewBuiltinClassResolver(tc.getNewBuiltinClassResolver());
-        }
-        if (tc.isNumberFormatSet()) {
-            setNumberFormat(tc.getNumberFormat());
-        }
-        if (tc.isObjectWrapperSet()) {
-            setObjectWrapper(tc.getObjectWrapper());
-        }
-        if (tc.isOutputEncodingSet()) {
-            setOutputEncoding(tc.getOutputEncoding());
-        }
-        if (tc.isOutputFormatSet()) {
-            setOutputFormat(tc.getOutputFormat());
-        }
-        if (tc.isRecognizeStandardFileExtensionsSet()) {
-            
setRecognizeStandardFileExtensions(tc.getRecognizeStandardFileExtensions());
-        }
-        if (tc.isShowErrorTipsSet()) {
-            setShowErrorTips(tc.getShowErrorTips());
-        }
-        if (tc.isSQLDateAndTimeTimeZoneSet()) {
-            setSQLDateAndTimeTimeZone(tc.getSQLDateAndTimeTimeZone());
-        }
-        if (tc.isTagSyntaxSet()) {
-            setTagSyntax(tc.getTagSyntax());
-        }
-        if (tc.isTemplateExceptionHandlerSet()) {
-            setTemplateExceptionHandler(tc.getTemplateExceptionHandler());
-        }
-        if (tc.isTimeFormatSet()) {
-            setTimeFormat(tc.getTimeFormat());
-        }
-        if (tc.isTimeZoneSet()) {
-            setTimeZone(tc.getTimeZone());
-        }
-        if (tc.isURLEscapingCharsetSet()) {
-            setURLEscapingCharset(tc.getURLEscapingCharset());
-        }
-        if (tc.isWhitespaceStrippingSet()) {
-            setWhitespaceStripping(tc.getWhitespaceStripping());
-        }
-        if (tc.isTabSizeSet()) {
-            setTabSize(tc.getTabSize());
-        }
-        if (tc.isLazyImportsSet()) {
-            setLazyImports(tc.getLazyImports());
-        }
-        if (tc.isLazyAutoImportsSet()) {
-            setLazyAutoImports(tc.getLazyAutoImports());
-        }
-        if (tc.isAutoImportsSet()) {
-            setAutoImports(mergeMaps(isAutoImportsSet() ? getAutoImports() : 
null, tc.getAutoImports(), true));
-        }
-        if (tc.isAutoIncludesSet()) {
-            setAutoIncludes(mergeLists(isAutoIncludesSet() ? getAutoIncludes() 
: null, tc.getAutoIncludes()));
-        }
-        
-        tc.copyDirectCustomAttributes(this, true);
-    }
-
-    /**
-     * Sets those settings of the {@link Template} which aren't yet set in the 
{@link Template} and are set in this
-     * {@link TemplateConfiguration}, leaves the other settings as is. A 
setting is said to be set in a
-     * {@link TemplateConfiguration} or {@link Template} if it was explicitly 
set via a setter method on that object, as
-     * opposed to be inherited from the {@link Configuration}.
-     * 
-     * <p>
-     * Note that this method doesn't deal with settings that influence the 
parser, as those are already baked in at this
-     * point via the {@link ParserConfiguration}. 
-     * 
-     * <p>
-     * Note that the {@code encoding} setting of the {@link Template} counts 
as unset if it's {@code null},
-     * even if {@code null} was set via {@link Template#setEncoding(String)}.
-     *
-     * @throws IllegalStateException
-     *             If the parent configuration wasn't yet set.
-     */
-    public void apply(Template template) {
-        Configuration cfg = getNonNullParentConfiguration();
-        if (template.getConfiguration() != cfg) {
-            // This is actually not a problem right now, but for future BC we 
enforce this.
-            throw new IllegalArgumentException(
-                    "The argument Template doesn't belong to the same 
Configuration as the TemplateConfiguration");
-        }
-
-        if (isAPIBuiltinEnabledSet() && !template.isAPIBuiltinEnabledSet()) {
-            template.setAPIBuiltinEnabled(isAPIBuiltinEnabled());
-        }
-        if (isArithmeticEngineSet() && !template.isArithmeticEngineSet()) {
-            template.setArithmeticEngine(getArithmeticEngine());
-        }
-        if (isAutoFlushSet() && !template.isAutoFlushSet()) {
-            template.setAutoFlush(getAutoFlush());
-        }
-        if (isBooleanFormatSet() && !template.isBooleanFormatSet()) {
-            template.setBooleanFormat(getBooleanFormat());
-        }
-        if (isCustomDateFormatsSet()) {
-            template.setCustomDateFormats(
-                    mergeMaps(getCustomDateFormats(), 
template.getCustomDateFormatsWithoutFallback(), false));
-        }
-        if (isCustomNumberFormatsSet()) {
-            template.setCustomNumberFormats(
-                    mergeMaps(getCustomNumberFormats(), 
template.getCustomNumberFormatsWithoutFallback(), false));
-        }
-        if (isDateFormatSet() && !template.isDateFormatSet()) {
-            template.setDateFormat(getDateFormat());
-        }
-        if (isDateTimeFormatSet() && !template.isDateTimeFormatSet()) {
-            template.setDateTimeFormat(getDateTimeFormat());
-        }
-        if (isEncodingSet() && template.getEncoding() == null) {
-            template.setEncoding(getEncoding());
-        }
-        if (isLocaleSet() && !template.isLocaleSet()) {
-            template.setLocale(getLocale());
-        }
-        if (isLogTemplateExceptionsSet() && 
!template.isLogTemplateExceptionsSet()) {
-            template.setLogTemplateExceptions(getLogTemplateExceptions());
-        }
-        if (isNewBuiltinClassResolverSet() && 
!template.isNewBuiltinClassResolverSet()) {
-            template.setNewBuiltinClassResolver(getNewBuiltinClassResolver());
-        }
-        if (isNumberFormatSet() && !template.isNumberFormatSet()) {
-            template.setNumberFormat(getNumberFormat());
-        }
-        if (isObjectWrapperSet() && !template.isObjectWrapperSet()) {
-            template.setObjectWrapper(getObjectWrapper());
-        }
-        if (isOutputEncodingSet() && !template.isOutputEncodingSet()) {
-            template.setOutputEncoding(getOutputEncoding());
-        }
-        if (isShowErrorTipsSet() && !template.isShowErrorTipsSet()) {
-            template.setShowErrorTips(getShowErrorTips());
-        }
-        if (isSQLDateAndTimeTimeZoneSet() && 
!template.isSQLDateAndTimeTimeZoneSet()) {
-            template.setSQLDateAndTimeTimeZone(getSQLDateAndTimeTimeZone());
-        }
-        if (isTemplateExceptionHandlerSet() && 
!template.isTemplateExceptionHandlerSet()) {
-            
template.setTemplateExceptionHandler(getTemplateExceptionHandler());
-        }
-        if (isTimeFormatSet() && !template.isTimeFormatSet()) {
-            template.setTimeFormat(getTimeFormat());
-        }
-        if (isTimeZoneSet() && !template.isTimeZoneSet()) {
-            template.setTimeZone(getTimeZone());
-        }
-        if (isURLEscapingCharsetSet() && !template.isURLEscapingCharsetSet()) {
-            template.setURLEscapingCharset(getURLEscapingCharset());
-        }
-        if (isLazyImportsSet() && !template.isLazyImportsSet()) {
-            template.setLazyImports(getLazyImports());
-        }
-        if (isLazyAutoImportsSet() && !template.isLazyAutoImportsSet()) {
-            template.setLazyAutoImports(getLazyAutoImports());
-        }
-        if (isAutoImportsSet()) {
-            // Regarding the order of the maps in the merge:
-            // - Existing template-level imports have precedence over those 
coming from the TC (just as with the others
-            //   apply()-ed settings), thus for clashing import prefixes they 
must win.
-            // - Template-level imports count as more specific, and so come 
after the more generic ones from TC.
-            template.setAutoImports(mergeMaps(getAutoImports(), 
template.getAutoImportsWithoutFallback(), true));
-        }
-        if (isAutoIncludesSet()) {
-            template.setAutoIncludes(mergeLists(getAutoIncludes(), 
template.getAutoIncludesWithoutFallback()));
-        }
-        
-        copyDirectCustomAttributes(template, false);
-    }
-
-    /**
-     * See {@link Configuration#setTagSyntax(int)}.
-     */
-    public void setTagSyntax(int tagSyntax) {
-        _TemplateAPI.valideTagSyntaxValue(tagSyntax);
-        this.tagSyntax = Integer.valueOf(tagSyntax);
-    }
-
-    /**
-     * The getter pair of {@link #setTagSyntax(int)}.
-     */
-    @Override
-    public int getTagSyntax() {
-        return tagSyntax != null ? tagSyntax.intValue() : 
getNonNullParentConfiguration().getTagSyntax();
-    }
-
-    /**
-     * Tells if this setting is set directly in this object or its value is 
coming from the {@link #getParent() parent}.
-     */
-    public boolean isTagSyntaxSet() {
-        return tagSyntax != null;
-    }
-
-    /**
-     * See {@link Configuration#setNamingConvention(int)}.
-     */
-    public void setNamingConvention(int namingConvention) {
-        _TemplateAPI.validateNamingConventionValue(namingConvention);
-        this.namingConvention = Integer.valueOf(namingConvention);
-    }
-
-    /**
-     * The getter pair of {@link #setNamingConvention(int)}.
-     */
-    @Override
-    public int getNamingConvention() {
-        return namingConvention != null ? namingConvention.intValue()
-                : getNonNullParentConfiguration().getNamingConvention();
-    }
-
-    /**
-     * Tells if this setting is set directly in this object or its value is 
coming from the {@link #getParent() parent}.
-     */
-    public boolean isNamingConventionSet() {
-        return namingConvention != null;
-    }
-
-    /**
-     * See {@link Configuration#setWhitespaceStripping(boolean)}.
-     */
-    public void setWhitespaceStripping(boolean whitespaceStripping) {
-        this.whitespaceStripping = Boolean.valueOf(whitespaceStripping);
-    }
-
-    /**
-     * The getter pair of {@link #getWhitespaceStripping()}.
-     */
-    @Override
-    public boolean getWhitespaceStripping() {
-        return whitespaceStripping != null ? whitespaceStripping.booleanValue()
-                : getNonNullParentConfiguration().getWhitespaceStripping();
-    }
-
-    /**
-     * Tells if this setting is set directly in this object or its value is 
coming from the {@link #getParent() parent}.
-     */
-    public boolean isWhitespaceStrippingSet() {
-        return whitespaceStripping != null;
-    }
-
-    /**
-     * Sets the output format of the template; see {@link 
Configuration#setAutoEscapingPolicy(int)} for more.
-     */
-    public void setAutoEscapingPolicy(int autoEscapingPolicy) {
-        _TemplateAPI.validateAutoEscapingPolicyValue(autoEscapingPolicy);
-        this.autoEscapingPolicy = Integer.valueOf(autoEscapingPolicy);
-    }
-
-    /**
-     * The getter pair of {@link #setAutoEscapingPolicy(int)}.
-     */
-    @Override
-    public int getAutoEscapingPolicy() {
-        return autoEscapingPolicy != null ? autoEscapingPolicy.intValue()
-                : getNonNullParentConfiguration().getAutoEscapingPolicy();
-    }
-
-    /**
-     * Tells if this setting is set directly in this object or its value is 
coming from the {@link #getParent() parent}.
-     */
-    public boolean isAutoEscapingPolicySet() {
-        return autoEscapingPolicy != null;
-    }
-
-    /**
-     * Sets the output format of the template; see {@link 
Configuration#setOutputFormat(OutputFormat)} for more.
-     */
-    public void setOutputFormat(OutputFormat outputFormat) {
-        _NullArgumentException.check("outputFormat", outputFormat);
-        this.outputFormat = outputFormat;
-    }
-
-    /**
-     * The getter pair of {@link #setOutputFormat(OutputFormat)}.
-     */
-    @Override
-    public OutputFormat getOutputFormat() {
-        return outputFormat != null ? outputFormat : 
getNonNullParentConfiguration().getOutputFormat();
-    }
-
-    /**
-     * Tells if this setting is set directly in this object or its value is 
coming from the {@link #getParent() parent}.
-     */
-    public boolean isOutputFormatSet() {
-        return outputFormat != null;
-    }
-    
-    /**
-     * See {@link Configuration#setRecognizeStandardFileExtensions(boolean)}. 
-     */
-    public void setRecognizeStandardFileExtensions(boolean 
recognizeStandardFileExtensions) {
-        this.recognizeStandardFileExtensions = 
Boolean.valueOf(recognizeStandardFileExtensions);
-    }
-
-    /**
-     * Getter pair of {@link #setRecognizeStandardFileExtensions(boolean)}.
-     */
-    @Override
-    public boolean getRecognizeStandardFileExtensions() {
-        return recognizeStandardFileExtensions != null ? 
recognizeStandardFileExtensions.booleanValue()
-                : 
getNonNullParentConfiguration().getRecognizeStandardFileExtensions();
-    }
-    
-    /**
-     * Tells if this setting is set directly in this object or its value is 
coming from the {@link #getParent() parent}.
-     */
-    public boolean isRecognizeStandardFileExtensionsSet() {
-        return recognizeStandardFileExtensions != null;
-    }
-
-    public String getEncoding() {
-        return encoding != null ? encoding : 
getNonNullParentConfiguration().getDefaultEncoding();
-    }
-
-    /**
-     * When the standard template loading/caching mechanism is used, this 
forces the charset used for reading the
-     * template "file", overriding everything but the encoding coming from the 
{@code #ftl} header. This setting
-     * overrides the locale-specific encodings set via {@link 
Configuration#setEncoding(java.util.Locale, String)}. It
-     * also overrides the {@code encoding} parameter of {@link 
Configuration#getTemplate(String, String)} (and of its
-     * overloads) and the {@code encoding} parameter of the {@code #include} 
directive. This works like that because
-     * specifying the encoding where you are requesting the template is error 
prone and deprecated.
-     * 
-     * <p>
-     * If you are developing your own template loading/caching mechanism 
instead of the standard one, note that the
-     * above behavior is not guaranteed by this class alone; you have to 
ensure it. Also, read the note on
-     * {@code encoding} in the documentation of {@link #apply(Template)}.
-     */
-    public void setEncoding(String encoding) {
-        _NullArgumentException.check("encoding", encoding);
-        this.encoding = encoding;
-    }
-
-    public boolean isEncodingSet() {
-        return encoding != null;
-    }
-    
-    /**
-     * See {@link Configuration#setTabSize(int)}. 
-     * 
-     * @since 2.3.25
-     */
-    public void setTabSize(int tabSize) {
-        this.tabSize = Integer.valueOf(tabSize);
-    }
-
-    /**
-     * Getter pair of {@link #setTabSize(int)}.
-     * 
-     * @since 2.3.25
-     */
-    @Override
-    public int getTabSize() {
-        return tabSize != null ? tabSize.intValue()
-                : getNonNullParentConfiguration().getTabSize();
-    }
-    
-    /**
-     * Tells if this setting is set directly in this object or its value is 
coming from the {@link #getParent() parent}.
-     * 
-     * @since 2.3.25
-     */
-    public boolean isTabSizeSet() {
-        return tabSize != null;
-    }
-    
-    /**
-     * Returns {@link Configuration#getIncompatibleImprovements()} from the 
parent {@link Configuration}. This mostly
-     * just exist to satisfy the {@link ParserConfiguration} interface.
-     * 
-     * @throws IllegalStateException
-     *             If the parent configuration wasn't yet set.
-     */
-    @Override
-    public Version getIncompatibleImprovements() {
-        return getNonNullParentConfiguration().getIncompatibleImprovements();
-    }
-    
-    
-
-    @Override
-    public Locale getLocale() {
-        try {
-            return super.getLocale();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public TimeZone getTimeZone() {
-        try {
-            return super.getTimeZone();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public TimeZone getSQLDateAndTimeTimeZone() {
-        try {
-            return super.getSQLDateAndTimeTimeZone();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public String getNumberFormat() {
-        try {
-            return super.getNumberFormat();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public Map<String, ? extends TemplateNumberFormatFactory> 
getCustomNumberFormats() {
-        try {
-            return super.getCustomNumberFormats();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public TemplateNumberFormatFactory getCustomNumberFormat(String name) {
-        try {
-            return super.getCustomNumberFormat(name);
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public boolean hasCustomFormats() {
-        try {
-            return super.hasCustomFormats();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public String getBooleanFormat() {
-        try {
-            return super.getBooleanFormat();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public String getTimeFormat() {
-        try {
-            return super.getTimeFormat();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public String getDateFormat() {
-        try {
-            return super.getDateFormat();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public String getDateTimeFormat() {
-        try {
-            return super.getDateTimeFormat();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public Map<String, ? extends TemplateDateFormatFactory> 
getCustomDateFormats() {
-        try {
-            return super.getCustomDateFormats();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public TemplateDateFormatFactory getCustomDateFormat(String name) {
-        try {
-            return super.getCustomDateFormat(name);
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public TemplateExceptionHandler getTemplateExceptionHandler() {
-        try {
-            return super.getTemplateExceptionHandler();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public ArithmeticEngine getArithmeticEngine() {
-        try {
-            return super.getArithmeticEngine();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public ObjectWrapper getObjectWrapper() {
-        try {
-            return super.getObjectWrapper();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public String getOutputEncoding() {
-        try {
-            return super.getOutputEncoding();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public String getURLEscapingCharset() {
-        try {
-            return super.getURLEscapingCharset();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public TemplateClassResolver getNewBuiltinClassResolver() {
-        try {
-            return super.getNewBuiltinClassResolver();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public boolean getAutoFlush() {
-        try {
-            return super.getAutoFlush();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public boolean getShowErrorTips() {
-        try {
-            return super.getShowErrorTips();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public boolean isAPIBuiltinEnabled() {
-        try {
-            return super.isAPIBuiltinEnabled();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public boolean getLogTemplateExceptions() {
-        try {
-            return super.getLogTemplateExceptions();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public boolean getLazyImports() {
-        try {
-            return super.getLazyImports();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public Boolean getLazyAutoImports() {
-        try {
-            return super.getLazyAutoImports();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public Map<String, String> getAutoImports() {
-        try {
-            return super.getAutoImports();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public List<String> getAutoIncludes() {
-        try {
-            return super.getAutoIncludes();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public String[] getCustomAttributeNames() {
-        try {
-            return super.getCustomAttributeNames();
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    @Override
-    public Object getCustomAttribute(String name) {
-        try {
-            return super.getCustomAttribute(name);
-        } catch (NullPointerException e) {
-            getNonNullParentConfiguration();
-            throw e;
-        }
-    }
-
-    private boolean hasAnyConfigurableSet() {
-        return
-                isAPIBuiltinEnabledSet()
-                || isArithmeticEngineSet()
-                || isAutoFlushSet()
-                || isAutoImportsSet()
-                || isAutoIncludesSet()
-                || isBooleanFormatSet()
-                || isCustomDateFormatsSet()
-                || isCustomNumberFormatsSet()
-                || isDateFormatSet()
-                || isDateTimeFormatSet()
-                || isLazyImportsSet()
-                || isLazyAutoImportsSet()
-                || isLocaleSet()
-                || isLogTemplateExceptionsSet()
-                || isNewBuiltinClassResolverSet()
-                || isNumberFormatSet()
-                || isObjectWrapperSet()
-                || isOutputEncodingSet()
-                || isShowErrorTipsSet()
-                || isSQLDateAndTimeTimeZoneSet()
-                || isTemplateExceptionHandlerSet()
-                || isTimeFormatSet()
-                || isTimeZoneSet()
-                || isURLEscapingCharsetSet();
-    }
-    
-    private Map mergeMaps(Map m1, Map m2, boolean overwriteUpdatesOrder) {
-        if (m1 == null) return m2;
-        if (m2 == null) return m1;
-        if (m1.isEmpty()) return m2 != null ? m2 : m1;
-        if (m2.isEmpty()) return m1 != null ? m1 : m2;
-        
-        LinkedHashMap mergedM = new LinkedHashMap((m1.size() + m2.size()) * 4 
/ 3 + 1, 0.75f);
-        mergedM.putAll(m1);
-        for (Object m2Key : m2.keySet()) {
-            mergedM.remove(m2Key); // So that duplicate keys are moved after 
m1 keys
-        }
-        mergedM.putAll(m2);
-        return mergedM;
-    }
-
-    private List<String> mergeLists(List<String> list1, List<String> list2) {
-        if (list1 == null) return list2;
-        if (list2 == null) return list1;
-        if (list1.isEmpty()) return list2 != null ? list2 : list1;
-        if (list2.isEmpty()) return list1 != null ? list1 : list2;
-        
-        ArrayList<String> mergedList = new ArrayList<>(list1.size() + 
list2.size());
-        mergedList.addAll(list1);
-        mergedList.addAll(list2);
-        return mergedList;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/TemplateDateFormat.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/ast/TemplateDateFormat.java 
b/src/main/java/org/apache/freemarker/core/ast/TemplateDateFormat.java
deleted file mode 100644
index a1babde..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/TemplateDateFormat.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.freemarker.core.ast;
-
-import java.text.DateFormat;
-import java.util.Date;
-
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-
-/**
- * Represents a date/time/dateTime format; used in templates for formatting 
and parsing with that format. This is
- * similar to Java's {@link DateFormat}, but made to fit the requirements of 
FreeMarker. Also, it makes easier to define
- * formats that can't be represented with Java's existing {@link DateFormat} 
implementations.
- * 
- * <p>
- * Implementations need not be thread-safe if the {@link 
TemplateNumberFormatFactory} doesn't recycle them among
- * different {@link Environment}-s. As far as FreeMarker's concerned, 
instances are bound to a single
- * {@link Environment}, and {@link Environment}-s are thread-local objects.
- * 
- * @since 2.3.24
- */
-public abstract class TemplateDateFormat extends TemplateValueFormat {
-    
-    /**
-     * @param dateModel
-     *            The date/time/dateTime to format; not {@code null}. Most 
implementations will just work with the return value of
-     *            {@link TemplateDateModel#getAsDate()}, but some may format 
differently depending on the properties of
-     *            a custom {@link TemplateDateModel} implementation.
-     * 
-     * @return The date/time/dateTime as text, with no escaping (like no HTML 
escaping); can't be {@code null}.
-     * 
-     * @throws TemplateValueFormatException
-     *             When a problem occurs during the formatting of the value. 
Notable subclass:
-     *             {@link UnknownDateTypeFormattingUnsupportedException}
-     * @throws TemplateModelException
-     *             Exception thrown by the {@code dateModel} object when 
calling its methods.
-     */
-    public abstract String formatToPlainText(TemplateDateModel dateModel)
-            throws TemplateValueFormatException, TemplateModelException;
-
-    /**
-     * Formats the model to markup instead of to plain text if the result 
markup will be more than just plain text
-     * escaped, otherwise falls back to formatting to plain text. If the 
markup result would be just the result of
-     * {@link #formatToPlainText(TemplateDateModel)} escaped, it must return 
the {@link String} that
-     * {@link #formatToPlainText(TemplateDateModel)} does.
-     * 
-     * <p>The implementation in {@link TemplateDateFormat} simply calls {@link 
#formatToPlainText(TemplateDateModel)}.
-     * 
-     * @return A {@link String} or a {@link TemplateMarkupOutputModel}; not 
{@code null}.
-     */
-    public Object format(TemplateDateModel dateModel) throws 
TemplateValueFormatException, TemplateModelException {
-        return formatToPlainText(dateModel);
-    }
-
-    /**
-     * Parsers a string to date/time/datetime, according to this format. Some 
format implementations may throw
-     * {@link ParsingNotSupportedException} here. 
-     * 
-     * @param s
-     *            The string to parse
-     * @param dateType
-     *            The expected date type of the result. Not all {@link 
TemplateDateFormat}-s will care about this;
-     *            though those who return a {@link TemplateDateModel} instead 
of {@link Date} often will. When strings
-     *            are parsed via {@code ?date}, {@code ?time}, or {@code 
?datetime}, then this parameter is
-     *            {@link TemplateDateModel#DATE}, {@link 
TemplateDateModel#TIME}, or {@link TemplateDateModel#DATETIME},
-     *            respectively. This parameter rarely if ever {@link 
TemplateDateModel#UNKNOWN}, but the implementation
-     *            that cares about this parameter should be prepared for that. 
If nothing else, it should throw
-     *            {@link UnknownDateTypeParsingUnsupportedException} then.
-     * 
-     * @return The interpretation of the text either as a {@link Date} or 
{@link TemplateDateModel}. Typically, a
-     *         {@link Date}. {@link TemplateDateModel} is used if you have to 
attach some application-specific
-     *         meta-information thats also extracted during {@link 
#formatToPlainText(TemplateDateModel)} (so if you format
-     *         something and then parse it, you get back an equivalent 
result). It can't be {@code null}. Known issue
-     *         (at least in FTL 2): {@code ?date}/{@code ?time}/{@code 
?datetime}, when not invoked as a method, can't
-     *         return the {@link TemplateDateModel}, only the {@link Date} 
from inside it, hence the additional
-     *         application-specific meta-info will be lost.
-     */
-    public abstract Object parse(String s, int dateType) throws 
TemplateValueFormatException;
-    
-    /**
-     * Tells if this formatter should be re-created if the locale changes.
-     */
-    public abstract boolean isLocaleBound();
-
-    /**
-     * Tells if this formatter should be re-created if the time zone changes. 
Currently always {@code true}.
-     */
-    public abstract boolean isTimeZoneBound();
-        
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/TemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/ast/TemplateDateFormatFactory.java 
b/src/main/java/org/apache/freemarker/core/ast/TemplateDateFormatFactory.java
deleted file mode 100644
index e02f0ef..0000000
--- 
a/src/main/java/org/apache/freemarker/core/ast/TemplateDateFormatFactory.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.
- */
-package org.apache.freemarker.core.ast;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateDateModel;
-
-/**
- * Factory for a certain kind of date/time/dateTime formatting ({@link 
TemplateDateFormat}). Usually a singleton
- * (one-per-VM or one-per-{@link Configuration}), and so must be thread-safe.
- * 
- * @see Configurable#setCustomDateFormats(java.util.Map)
- * 
- * @since 2.3.24
- */
-public abstract class TemplateDateFormatFactory extends 
TemplateValueFormatFactory {
-    
-    /**
-     * Returns a formatter for the given parameters.
-     * 
-     * <p>
-     * The returned formatter can be a new instance or a reused (cached) 
instance. Note that {@link Environment} itself
-     * caches the returned instances, though that cache is lost with the 
{@link Environment} (i.e., when the top-level
-     * template execution ends), also it might flushes lot of entries if the 
locale or time zone is changed during
-     * template execution. So caching on the factory level is still useful, 
unless creating the formatters is
-     * sufficiently cheap.
-     * 
-     * @param params
-     *            The string that further describes how the format should 
look. For example, when the
-     *            {@link Configurable#getDateFormat() dateFormat} is {@code 
"@fooBar 1, 2"}, then it will be
-     *            {@code "1, 2"} (and {@code "@fooBar"} selects the factory). 
The format of this string is up to the
-     *            {@link TemplateDateFormatFactory} implementation. Not {@code 
null}, often an empty string.
-     * @param dateType
-     *            {@link TemplateDateModel#DATE}, {@link 
TemplateDateModel#TIME}, {@link TemplateDateModel#DATETIME} or
-     *            {@link TemplateDateModel#UNKNOWN}. Supporting {@link 
TemplateDateModel#UNKNOWN} is not necessary, in
-     *            which case the method should throw an {@link 
UnknownDateTypeFormattingUnsupportedException} exception.
-     * @param locale
-     *            The locale to format for. Not {@code null}. The resulting 
format should be bound to this locale
-     *            forever (i.e. locale changes in the {@link Environment} must 
not be followed).
-     * @param timeZone
-     *            The time zone to format for. Not {@code null}. The resulting 
format must be bound to this time zone
-     *            forever (i.e. time zone changes in the {@link Environment} 
must not be followed).
-     * @param zonelessInput
-     *            Indicates that the input Java {@link Date} is not from a 
time zone aware source. When this is
-     *            {@code true}, the formatters shouldn't override the time 
zone provided to its constructor (most
-     *            formatters don't do that anyway), and it shouldn't show the 
time zone, if it can hide it (like a
-     *            {@link SimpleDateFormat} pattern-based formatter may can't 
do that, as the pattern prescribes what to
-     *            show).
-     *            <p>
-     *            As of FreeMarker 2.3.21, this is {@code true} exactly when 
the date is an SQL "date without time of
-     *            the day" (i.e., a {@link java.sql.Date java.sql.Date}) or an 
SQL "time of the day" value (i.e., a
-     *            {@link java.sql.Time java.sql.Time}, although this rule can 
change in future, depending on
-     *            configuration settings and such, so you shouldn't rely on 
this rule, just accept what this parameter
-     *            says.
-     * @param env
-     *            The runtime environment from which the formatting was 
called. This is mostly meant to be used for
-     *            {@link Environment#setCustomState(Object, Object)}/{@link 
Environment#getCustomState(Object)}.
-     * 
-     * @throws TemplateValueFormatException
-     *             If any problem occurs while parsing/getting the format. 
Notable subclasses:
-     *             {@link InvalidFormatParametersException} if {@code params} 
is malformed;
-     *             {@link UnknownDateTypeFormattingUnsupportedException} if 
{@code dateType} is
-     *             {@link TemplateDateModel#UNKNOWN} and that's unsupported by 
this factory.
-     */
-    public abstract TemplateDateFormat get(
-            String params,
-            int dateType, Locale locale, TimeZone timeZone, boolean 
zonelessInput,
-            Environment env)
-                    throws TemplateValueFormatException;
-
-}

Reply via email to