http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/core/UnboundTemplate.java
----------------------------------------------------------------------
diff --cc src/main/java/freemarker/core/UnboundTemplate.java
index d464d3d,0000000..7f7e96e
mode 100644,000000..100644
--- a/src/main/java/freemarker/core/UnboundTemplate.java
+++ b/src/main/java/freemarker/core/UnboundTemplate.java
@@@ -1,599 -1,0 +1,602 @@@
 +/*
-  * Copyright 2014 Attila Szegedi, Daniel Dekany, Jonathan Revusky
++ * 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
 + * 
-  * Licensed 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
 + * 
-  * 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.
++ * 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 freemarker.core;
 +
 +import java.io.BufferedReader;
 +import java.io.FilterReader;
 +import java.io.IOException;
 +import java.io.PrintStream;
 +import java.io.Reader;
 +import java.io.StringReader;
 +import java.io.StringWriter;
 +import java.io.Writer;
 +import java.lang.reflect.UndeclaredThrowableException;
 +import java.util.ArrayList;
 +import java.util.Collections;
 +import java.util.Enumeration;
 +import java.util.HashMap;
 +import java.util.LinkedHashMap;
 +import java.util.List;
 +import java.util.Map;
 +
 +import freemarker.cache.TemplateLoader;
 +import freemarker.template.Configuration;
 +import freemarker.template.Template;
 +import freemarker.template.Template.WrongEncodingException;
 +import freemarker.template.Version;
 +import freemarker.template._TemplateAPI;
 +import freemarker.template.utility.NullArgumentException;
 +
 +/**
 + * The parsed representation of a template that's not yet bound to the {@link 
Template} properties that doesn't
 + * influence the result of the parsing. This information wasn't separated 
from {@link Template} in FreeMarker 2.3.x,
 + * and was factored out from it into this class in 2.4.0, to allow more 
efficient caching.
 + * 
 + * @since 2.4.0
 + */
 +public final class UnboundTemplate {
 +
 +    public static final String DEFAULT_NAMESPACE_PREFIX = "D";
 +    public static final String NO_NS_PREFIX = "N";
 +
 +    private final String sourceName;
 +    private final Configuration cfg;
 +    private final ParserConfiguration parserCfg;
 +    private final Version templateLanguageVersion;
 +    
 +    /** Attributes added via {@code <#ftl attributes=...>}. */
 +    private LinkedHashMap<String, Object> customAttributes;
 +    private final Map<String, UnboundCallable> unboundCallables = new 
HashMap<String, UnboundCallable>(0);
 +    // Earlier it was a Vector, so I thought the safest is to keep it 
synchronized:
 +    private final List<LibraryLoad> imports = 
Collections.synchronizedList(new ArrayList<LibraryLoad>(0));
 +    private final TemplateElement rootElement;
 +    private String defaultNamespaceURI;
 +    private final int actualTagSyntax;
 +    private final int actualNamingConvention;
 +    private OutputFormat outputFormat;
 +    private boolean autoEscaping;
 +    
 +    private final String templateSpecifiedEncoding;
 +    
 +    private final ArrayList lines = new ArrayList();
 +    
 +    private Map<String, String> prefixToNamespaceURIMapping;
 +    private Map<String, String> namespaceURIToPrefixMapping;
 +
 +    /**
 +     * @param reader
 +     *            Reads the template source code
 +     * @param cfg
 +     *            The FreeMarker configuration settings; the resulting {@link 
UnboundTemplate} will be bound to this.
 +     * @param customParserCfg
 +     *            Overrides the parsing related configuration settings of the 
{@link Configuration} parameter; can be
 +     *            {@code null}. See the similar paramter of
 +     *            {@link Template#Template(String, String, Reader, 
Configuration, ParserConfiguration, String)} for more
 +     *            details.
 +     * @param assumedEncoding
 +     *            This is the name of the charset that we are supposed to be 
using. This is only needed to check if the
 +     *            encoding specified in the {@code #ftl} header (if any) 
matches this. If this is non-{@code null} and
 +     *            they don't match, a {@link WrongEncodingException} will be 
thrown by the parser.
 +     * @param sourceName
 +     *            Shown in error messages as the template "file" location.
 +     */
 +    UnboundTemplate(Reader reader, String sourceName, Configuration cfg, 
ParserConfiguration customParserCfg,
 +            String assumedEncoding)
 +            throws IOException {
 +        NullArgumentException.check(cfg);
 +        this.cfg = cfg;
 +        this.parserCfg = customParserCfg != null ? customParserCfg : cfg;
 +        this.sourceName = sourceName;
 +        this.templateLanguageVersion = normalizeTemplateLanguageVersion(
 +                getParserConfiguration().getIncompatibleImprovements());
 +
 +        LineTableBuilder ltbReader;
 +        try {
 +            if (!(reader instanceof BufferedReader) && !(reader instanceof 
StringReader)) {
 +                reader = new BufferedReader(reader, 0x1000);
 +            }
 +            ltbReader = new LineTableBuilder(reader);
 +            reader = ltbReader;
 +
 +            try {
 +                FMParser parser = new FMParser(this, reader, assumedEncoding, 
getParserConfiguration());
 +                
 +                TemplateElement rootElement;
 +                try {
 +                    rootElement = parser.Root();
 +                } catch (IndexOutOfBoundsException exc) {
 +                    // There's a JavaCC bug where the Reader throws a 
RuntimeExcepton and then JavaCC fails with
 +                    // IndexOutOfBoundsException. If that wasn't the case, we 
just rethrow. Otherwise we suppress the
 +                    // IndexOutOfBoundsException and let the real cause to be 
thrown later. 
 +                    if (!ltbReader.hasFailure()) {
 +                        throw exc;
 +                    }
 +                    rootElement = null;
 +                }
 +                this.rootElement = rootElement;
 +                
 +                this.actualTagSyntax = parser._getLastTagSyntax();
 +                this.actualNamingConvention = 
parser._getLastNamingConvention();
 +                this.templateSpecifiedEncoding = 
parser._getTemplateSpecifiedEncoding();
 +            } catch (TokenMgrError exc) {
 +                // TokenMgrError VS ParseException is not an interesting 
difference for the user, so we just convert it
 +                // to ParseException
 +                throw exc.toParseException(this);
 +            }
 +        } catch (ParseException e) {
 +            e.setTemplateName(getSourceName());
 +            throw e;
 +        } finally {
 +            reader.close();
 +        }
 +        
 +        // Throws any exception that JavaCC has silently treated as EOF:
 +        ltbReader.throwFailure();
 +
 +        if (prefixToNamespaceURIMapping != null) {
 +            prefixToNamespaceURIMapping = 
Collections.unmodifiableMap(prefixToNamespaceURIMapping);
 +            namespaceURIToPrefixMapping = 
Collections.unmodifiableMap(namespaceURIToPrefixMapping);
 +        }
 +    }
 +    
 +    /**
 +     * Creates a plain text (unparsed) template. 
 +     */
 +    static UnboundTemplate newPlainTextUnboundTemplate(String content, String 
sourceName, Configuration cfg) {
 +        UnboundTemplate template;
 +        try {
 +            template = new UnboundTemplate(new StringReader("X"), sourceName, 
cfg, null, null);
 +        } catch (IOException e) {
 +            throw new BugException("Plain text template creation failed", e);
 +        }
 +        ((TextBlock) template.rootElement).replaceText(content);
 +        return template;
 +    }
 +    
 +    private static Version normalizeTemplateLanguageVersion(Version 
incompatibleImprovements) {
 +        
_TemplateAPI.checkVersionNotNullAndSupported(incompatibleImprovements);
 +        int v = incompatibleImprovements.intValue();
 +        if (v < _TemplateAPI.VERSION_INT_2_3_19) {
 +            return Configuration.VERSION_2_3_0;
 +        } else if (v > _TemplateAPI.VERSION_INT_2_3_21) {
 +            return Configuration.VERSION_2_3_21;
 +        } else { // if 2.3.19 or 2.3.20 or 2.3.21
 +            return incompatibleImprovements;
 +        }
 +    }
 +    
 +    /**
 +     * Returns a string representing the raw template text in canonical form.
 +     */
 +    @Override
 +    public String toString() {
 +        StringWriter sw = new StringWriter();
 +        try {
 +            dump(sw);
 +        } catch (IOException ioe) {
 +            throw new RuntimeException(ioe.getMessage());
 +        }
 +        return sw.toString();
 +    }
 +
 +    /**
 +     * The name that was actually used to load this template from the {@link 
TemplateLoader} (or from other custom
 +     * storage mechanism). This is what should be shown in error messages as 
the error location.
 +     * 
 +     * @see Template#getSourceName()
 +     */
 +    public String getSourceName() {
 +        return sourceName;
 +    }
 +
 +    /**
 +     * Return the template language (FTL) version used by this template. For 
now (2.3.21) this is the same as
 +     * {@link Configuration#getIncompatibleImprovements()}, except that it's 
normalized to the lowest version where the
 +     * template language was changed.
 +     */
 +    public Version getTemplateLanguageVersion() {
 +        return templateLanguageVersion;
 +    }
 +
 +    /**
 +     * See {@link Template#getActualTagSyntax()}.
 +     */
 +    public int getActualTagSyntax() {
 +        return actualTagSyntax;
 +    }
 +    
 +    /**
 +     * See {@link Template#getActualNamingConvention()}.
 +     */
 +    public int getActualNamingConvention() {
 +        return actualNamingConvention;
 +    }
 +    
 +    /**
 +     * See {@link Template#getOutputFormat()}.
 +     */
 +    public OutputFormat getOutputFormat() {
 +        return outputFormat;
 +    }
 +    
 +    /**
 +     * Meant to be called by the parser only. 
 +     */
 +    void setOutputFormat(OutputFormat outputFormat) {
 +        this.outputFormat = outputFormat;
 +    }
 +    
 +    /**
 +     * See {@link Template#getAutoEscaping()}.
 +     */
 +    public boolean getAutoEscaping() {
 +        return autoEscaping;
 +    }
 +
 +    /**
 +     * Meant to be called by the parser only. 
 +     */
 +    void setAutoEscaping(boolean autoEscaping) {
 +        this.autoEscaping = autoEscaping;
 +    }
 +    
 +    public Configuration getConfiguration() {
 +        return cfg;
 +    }
 +    
 +    /**
 +     * Returns the parser configuration that was in effect when creating this 
template; never {@code null}.
 +     * See {@link Template#getParserConfiguration()} for details.
 +     */
 +    public ParserConfiguration getParserConfiguration() {
 +        return parserCfg;
 +    }
 +
 +    /**
 +     * Dump the raw template in canonical form.
 +     */
 +    public void dump(PrintStream ps) {
 +        ps.print(rootElement.getCanonicalForm());
 +    }
 +
 +    /**
 +     * Dump the raw template in canonical form.
 +     */
 +    public void dump(Writer out) throws IOException {
 +        out.write(rootElement.getCanonicalForm());
 +    }
 +
 +    /**
 +     * Called by code internally to maintain a table of macros
 +     */
 +    void addUnboundCallable(UnboundCallable unboundCallable) {
 +        unboundCallables.put(unboundCallable.getName(), unboundCallable);
 +    }
 +
 +    /**
 +     * Called by code internally to maintain a list of imports
 +     */
 +    void addImport(LibraryLoad libLoad) {
 +        imports.add(libLoad);
 +    }
 +
 +    /**
 +     * Returns the template source at the location specified by the 
coordinates given, or {@code null} if unavailable.
 +     * 
 +     * @param beginColumn
 +     *            the first column of the requested source, 1-based
 +     * @param beginLine
 +     *            the first line of the requested source, 1-based
 +     * @param endColumn
 +     *            the last column of the requested source, 1-based
 +     * @param endLine
 +     *            the last line of the requested source, 1-based
 +     * @see freemarker.core.TemplateObject#getSource()
 +     */
 +    public String getSource(int beginColumn,
 +            int beginLine,
 +            int endColumn,
 +            int endLine) {
 +        if (beginLine < 1 || endLine < 1) return null; // dynamically 
?eval-ed expressions has no source available
 +
 +        // Our container is zero-based.
 +        --beginLine;
 +        --beginColumn;
 +        --endColumn;
 +        --endLine;
 +        StringBuilder buf = new StringBuilder();
 +        for (int i = beginLine; i <= endLine; i++) {
 +            if (i < lines.size()) {
 +                buf.append(lines.get(i));
 +            }
 +        }
 +        int lastLineLength = lines.get(endLine).toString().length();
 +        int trailingCharsToDelete = lastLineLength - endColumn - 1;
 +        buf.delete(0, beginColumn);
 +        buf.delete(buf.length() - trailingCharsToDelete, buf.length());
 +        return buf.toString();
 +    }
 +
 +    /**
 +     * Used internally by the parser.
 +     */
 +    void setCustomAttribute(String key, Object value) {
 +        LinkedHashMap<String, Object> attrs = customAttributes;
 +        if (attrs == null) {
 +            attrs = new LinkedHashMap<String, Object>();
 +            customAttributes = attrs;
 +        }
 +        attrs.put(key, value);
 +    }
 +
 +    /**
 +     * Returns the {@link Map} of custom attributes that are normally coming 
from the {@code #ftl} header, or
 +     * {@code null} if there was none. The returned {@code Map} must not be 
modified, and might changes during
 +     * template parsing as new attributes are added by the parser (i.e., it's 
not a snapshot).
 +     */
 +    Map<String, ?> getCustomAttributes() {
 +        return this.customAttributes;
 +    }
 +
 +    /**
 +     * @return the root TemplateElement object.
 +     */
 +    TemplateElement getRootTreeNode() {
 +        return rootElement;
 +    }
 +
 +    Map<String, UnboundCallable> getUnboundCallables() {
 +        return unboundCallables;
 +    }
 +
 +    List<LibraryLoad> getImports() {
 +        return imports;
 +    }
 +
 +    /**
 +     * This is used internally.
 +     */
 +    void addPrefixToNamespaceURIMapping(String prefix, String nsURI) {
 +        if (nsURI.length() == 0) {
 +            throw new IllegalArgumentException("Cannot map empty string URI");
 +        }
 +        if (prefix.length() == 0) {
 +            throw new IllegalArgumentException("Cannot map empty string 
prefix");
 +        }
 +        if (prefix.equals(NO_NS_PREFIX)) {
 +            throw new IllegalArgumentException("The prefix: " + prefix
 +                    + " cannot be registered, it's reserved for special 
internal use.");
 +        }
 +        
 +        if (prefixToNamespaceURIMapping != null) {
 +            if (prefixToNamespaceURIMapping.containsKey(prefix)) {
 +                throw new IllegalArgumentException("The prefix: '" + prefix + 
"' was repeated. This is illegal.");
 +            }
 +            if (namespaceURIToPrefixMapping.containsKey(nsURI)) {
 +                throw new IllegalArgumentException("The namespace URI: " + 
nsURI
 +                        + " cannot be mapped to 2 different prefixes.");
 +            }
 +        }
 +        
 +        if (prefix.equals(DEFAULT_NAMESPACE_PREFIX)) {
 +            this.defaultNamespaceURI = nsURI;
 +        } else {
 +            if (prefixToNamespaceURIMapping == null) {
 +                prefixToNamespaceURIMapping = new HashMap<String, String>();  
              
 +                namespaceURIToPrefixMapping = new HashMap<String, String>();
 +            }
 +            prefixToNamespaceURIMapping.put(prefix, nsURI);
 +            namespaceURIToPrefixMapping.put(nsURI, prefix);
 +        }
 +    }
 +
 +    public String getDefaultNamespaceURI() {
 +        return this.defaultNamespaceURI;
 +    }
 +
 +    /**
 +     * @return The namespace URI mapped to this node value prefix, or {@code 
null}.
 +     */
 +    public String getNamespaceURIForPrefix(String prefix) {
 +        if (prefix.equals("")) {
 +            return defaultNamespaceURI == null ? "" : defaultNamespaceURI;
 +        }
 +        
 +        final Map<String, String> m = prefixToNamespaceURIMapping;
 +        return m != null ? m.get(prefix) : null;
 +    }
 +    
 +    /**
 +     * The encoding (charset name) specified by the template itself (as of 
2.3.22, via {@code <#ftl encoding=...>}), or
 +     * {@code null} if none was specified.
 +     */
 +    public String getTemplateSpecifiedEncoding() {
 +        return templateSpecifiedEncoding;
 +    }
 +
 +    /**
 +     * @return the prefix mapped to this nsURI in this template. (Or null if 
there is none.)
 +     */
 +    public String getPrefixForNamespaceURI(String nsURI) {
 +        if (nsURI == null) {
 +            return null;
 +        }
 +        if (nsURI.length() == 0) {
 +            return defaultNamespaceURI == null ? "" : NO_NS_PREFIX;
 +        }
 +        if (nsURI.equals(defaultNamespaceURI)) {
 +            return "";
 +        }
 +        
 +        final Map<String, String> m = namespaceURIToPrefixMapping;
 +        return m != null ? m.get(nsURI) : null;
 +    }
 +
 +    /**
 +     * @return the prefixed name, based on the ns_prefixes defined in this 
template's header for the local name and node
 +     *         namespace passed in as parameters.
 +     */
 +    public String getPrefixedName(String localName, String nsURI) {
 +        if (nsURI == null || nsURI.length() == 0) {
 +            if (defaultNamespaceURI != null) {
 +                return NO_NS_PREFIX + ":" + localName;
 +            } else {
 +                return localName;
 +            }
 +        }
 +        if (nsURI.equals(defaultNamespaceURI)) {
 +            return localName;
 +        }
 +        String prefix = getPrefixForNamespaceURI(nsURI);
 +        if (prefix == null) {
 +            return null;
 +        }
 +        return prefix + ":" + localName;
 +    }
 +
 +    /**
 +     * @return an array of the {@link TemplateElement}s containing the given 
column and line numbers.
 +     */
 +    List<TemplateElement> containingElements(int column, int line) {
 +        final ArrayList<TemplateElement> elements = new 
ArrayList<TemplateElement>();
 +        TemplateElement element = rootElement;
 +        mainloop: while (element.contains(column, line)) {
 +            elements.add(element);
 +            for (Enumeration enumeration = element.children(); 
enumeration.hasMoreElements(); ) {
 +                TemplateElement elem = (TemplateElement) 
enumeration.nextElement();
 +                if (elem.contains(column, line)) {
 +                    element = elem;
 +                    continue mainloop;
 +                }
 +            }
 +            break;
 +        }
 +        return elements.isEmpty() ? null : elements;
 +    }
 +
 +    /**
 +     * Reader that builds up the line table info for us, and also helps in 
working around JavaCC's exception
 +     * suppression.
 +     */
 +    private class LineTableBuilder extends FilterReader {
 +        
 +        private final StringBuilder lineBuf = new StringBuilder();
 +        int lastChar;
 +        boolean closed;
 +        
 +        /** Needed to work around JavaCC behavior where it silently treats 
any errors as EOF. */ 
 +        private Exception failure; 
 +
 +        /**
 +         * @param r the character stream to wrap
 +         */
 +        LineTableBuilder(Reader r) {
 +            super(r);
 +        }
 +        
 +        public boolean hasFailure() {
 +            return failure != null;
 +        }
 +
 +        public void throwFailure() throws IOException {
 +            if (failure != null) {
 +                if (failure instanceof IOException) {
 +                    throw (IOException) failure;
 +                }
 +                if (failure instanceof RuntimeException) {
 +                    throw (RuntimeException) failure;
 +                }
 +                throw new UndeclaredThrowableException(failure);
 +            }
 +        }
 +
 +        @Override
 +        public int read() throws IOException {
 +            try {
 +                int c = in.read();
 +                handleChar(c);
 +                return c;
 +            } catch (Exception e) {
 +                throw rememberException(e);
 +            }
 +        }
 +
 +        private IOException rememberException(Exception e) throws IOException 
{
 +            // JavaCC used to read from the Reader after it was closed. So we 
must not treat that as a failure. 
 +            if (!closed) {
 +                failure = e;
 +            }
 +            if (e instanceof IOException) {
 +                return (IOException) e;
 +            }
 +            if (e instanceof RuntimeException) {
 +                throw (RuntimeException) e;
 +            }
 +            throw new UndeclaredThrowableException(e);
 +        }
 +
 +        @Override
 +        public int read(char cbuf[], int off, int len) throws IOException {
 +            try {
 +                int numchars = in.read(cbuf, off, len);
 +                for (int i = off; i < off + numchars; i++) {
 +                    char c = cbuf[i];
 +                    handleChar(c);
 +                }
 +                return numchars;
 +            } catch (Exception e) {
 +                throw rememberException(e);
 +            }
 +        }
 +
 +        @Override
 +        public void close() throws IOException {
 +            if (lineBuf.length() > 0) {
 +                lines.add(lineBuf.toString());
 +                lineBuf.setLength(0);
 +            }
 +            super.close();
 +            closed = true;
 +        }
 +
 +        private void handleChar(int c) {
 +            if (c == '\n' || c == '\r') {
 +                if (lastChar == '\r' && c == '\n') { // CRLF under Windoze
 +                    int lastIndex = lines.size() - 1;
 +                    String lastLine = (String) lines.get(lastIndex);
 +                    lines.set(lastIndex, lastLine + '\n');
 +                } else {
 +                    lineBuf.append((char) c);
 +                    lines.add(lineBuf.toString());
 +                    lineBuf.setLength(0);
 +                }
 +            } else if (c == '\t') {
 +                int numSpaces = 8 - (lineBuf.length() % 8);
 +                for (int i = 0; i < numSpaces; i++) {
 +                    lineBuf.append(' ');
 +                }
 +            } else {
 +                lineBuf.append((char) c);
 +            }
 +            lastChar = c;
 +        }
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/core/UnifiedCall.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/core/_2_4_OrLaterMarker.java
----------------------------------------------------------------------
diff --cc src/main/java/freemarker/core/_2_4_OrLaterMarker.java
index 5cb1247,0000000..81736a1
mode 100644,000000..100644
--- a/src/main/java/freemarker/core/_2_4_OrLaterMarker.java
+++ b/src/main/java/freemarker/core/_2_4_OrLaterMarker.java
@@@ -1,25 -1,0 +1,28 @@@
 +/*
-  * Copyright 2014 Attila Szegedi, Daniel Dekany, Jonathan Revusky
++ * 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
 + * 
-  * Licensed 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
 + * 
-  * 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.
++ * 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 freemarker.core;
 +
 +/**
 + * Don't use this; used internally by FreeMarker, might changes without 
notice.
 + * Used internally for detecting duplicate FreeMarker jar-s with different 
versions.
 + */
 +public class _2_4_OrLaterMarker {
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/core/_CoreAPI.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/core/_ErrorDescriptionBuilder.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/ext/jdom/NodeListModel.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/template/Configuration.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/template/Template.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/template/TemplateException.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/template/_TemplateAPI.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/template/utility/ClassUtil.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/template/utility/CollectionUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/java/freemarker/template/utility/StringUtil.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/main/javacc/FTL.jj
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/test/java/freemarker/core/CustomAttributeInUnboundTemplatesTest.java
----------------------------------------------------------------------
diff --cc 
src/test/java/freemarker/core/CustomAttributeInUnboundTemplatesTest.java
index 5243f1d,0000000..4cc3ed1
mode 100644,000000..100644
--- a/src/test/java/freemarker/core/CustomAttributeInUnboundTemplatesTest.java
+++ b/src/test/java/freemarker/core/CustomAttributeInUnboundTemplatesTest.java
@@@ -1,44 -1,0 +1,62 @@@
++/*
++ * 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 freemarker.core;
 +
 +import static org.junit.Assert.*;
 +
 +import java.io.IOException;
 +import java.io.StringReader;
 +
 +import org.junit.Test;
 +
 +import com.google.common.collect.ImmutableMap;
 +
 +import freemarker.template.Configuration;
 +import freemarker.template.Template;
 +
 +@SuppressWarnings("boxing")
 +public class CustomAttributeInUnboundTemplatesTest {
 +
 +    @Test
 +    public void inFtlHeaderTest() throws IOException {
 +        Template t = new Template(null, "<#ftl attributes={'a': 1?int}>", new 
Configuration(Configuration.VERSION_2_3_23));
 +        t.setCustomAttribute("b", 2);
 +        assertEquals(1, t.getCustomAttribute("a"));
 +        assertEquals(2, t.getCustomAttribute("b"));
 +        assertEquals(ImmutableMap.of("a", 1), 
t.getUnboundTemplate().getCustomAttributes());
 +    }
 +    
 +    @Test
 +    public void inTemplateConfigurerTest() throws IOException {
 +        Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
 +        
 +        TemplateConfigurer tc = new TemplateConfigurer();
 +        tc.setCustomAttribute("a", 1);
 +        tc.setParentConfiguration(cfg);
 +        
 +        Template t = new Template(null, null, new StringReader(""), cfg, tc, 
null);
 +        t.setCustomAttribute("b", 2);
 +        assertNull(t.getCustomAttribute("a"));
 +        tc.configure(t);
 +        assertEquals(1, t.getCustomAttribute("a"));
 +        assertEquals(2, t.getCustomAttribute("b"));
 +        assertNull(t.getUnboundTemplate().getCustomAttributes());
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/test/java/freemarker/core/DirectiveCallPlaceTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/test/java/freemarker/core/EnvironmentGetTemplateVariantsTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/test/java/freemarker/template/CustomAttributeTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/test/java/freemarker/template/MistakenlyPublicImportAPIsTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/991e284f/src/test/java/freemarker/template/MistakenlyPublicMacroAPIsTest.java
----------------------------------------------------------------------

Reply via email to