You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/03/20 17:32:26 UTC

[2/2] incubator-freemarker git commit: - Configuration.getTemplate has no "encoding" parameter anymore. Similarly #include has no "encoding" parameter either. The charset of templates can be specified via Configuration.defaultEncoding and Configuration.t

- Configuration.getTemplate has no "encoding" parameter anymore. Similarly #include has no "encoding" parameter either. The charset of templates can be specified via Configuration.defaultEncoding and Configuration.templateConfigurations (for example based on the directory it is in), or wirh the #ftl directive inside the template. Thus, a given template always has the same charset, no mater how it's accessed.

- Removed Configuration.setEncoding(java.util.Locale, String) and the related other methods. Because of the new logic of template encodings, the locale to encoding mapping doesn't make much sense anymore.
- #include-d/#import-ed templates don't inheirit the charset (encoding) of the #include-ing/#import-ing template. (Because, again, the charset of a template file is independent of how you access it.)
- Require customLookupCondition-s to be Serializable.


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/f6a693c5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/f6a693c5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/f6a693c5

Branch: refs/heads/3
Commit: f6a693c5734130b82aa5f3c40824f27fb86355e7
Parents: e365f11
Author: ddekany <dd...@apache.org>
Authored: Mon Mar 20 10:28:02 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Mon Mar 20 18:32:10 2017 +0100

----------------------------------------------------------------------
 .../apache/freemarker/core/ASTDirInclude.java   |  49 +--
 .../apache/freemarker/core/Configuration.java   | 253 ++-------------
 .../org/apache/freemarker/core/Environment.java |  61 ++--
 .../apache/freemarker/core/ParameterRole.java   |   1 -
 .../org/apache/freemarker/core/Template.java    |  25 +-
 .../freemarker/core/TemplateConfiguration.java  |   6 +-
 .../core/TemplateNotFoundException.java         |   3 +-
 .../templateresolver/GetTemplateResult.java     |   3 +-
 .../templateresolver/TemplateLoaderSession.java |   3 +-
 .../templateresolver/TemplateLookupContext.java |   2 +-
 .../core/templateresolver/TemplateResolver.java |  10 +-
 .../impl/DefaultTemplateResolver.java           | 102 +++---
 .../freemarker/dom/JaxenXPathSupport.java       |   6 +-
 .../freemarker/servlet/FreemarkerServlet.java   |   3 +-
 src/main/javacc/FTL.jj                          |  10 +-
 src/manual/en_US/FM3-CHANGE-LOG.txt             |  17 +-
 .../freemarker/core/ConfigurationTest.java      | 132 ++------
 .../freemarker/core/TemplatGetEncodingTest.java |  87 -----
 ...igurationWithDefaltTemplateResolverTest.java | 260 +++++++++++++++
 ...teConfigurationWithTemplateResolverTest.java | 321 -------------------
 .../core/TemplateGetEncodingTest.java           |  59 ++++
 .../core/TemplateLookupStrategyTest.java        |  78 +++--
 .../core/TemplateNotFoundMessageTest.java       |   8 +-
 .../DefaultTemplateResolverTest.java            | 136 +-------
 .../test/templatesuite/TemplateTestCase.java    |   4 -
 .../test/templatesuite/expected/include2.txt    |   5 -
 .../templates/charset-in-header_inc2.ftl        |   2 +-
 .../templates/include2-included-encoding.ftl    |  20 --
 .../test/templatesuite/templates/include2.ftl   |   6 -
 .../freemarker/test/templatesuite/testcases.xml |   5 +-
 30 files changed, 562 insertions(+), 1115 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/ASTDirInclude.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ASTDirInclude.java b/src/main/java/org/apache/freemarker/core/ASTDirInclude.java
index 9a51f16..46f71f3 100644
--- a/src/main/java/org/apache/freemarker/core/ASTDirInclude.java
+++ b/src/main/java/org/apache/freemarker/core/ASTDirInclude.java
@@ -21,52 +21,26 @@ package org.apache.freemarker.core;
 
 import java.io.IOException;
 
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
 import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException;
 import org.apache.freemarker.core.util.BugException;
 import org.apache.freemarker.core.util._StringUtil;
 
-
 /**
  * AST directive node: {@code #include} 
  */
 final class ASTDirInclude extends ASTDirective {
 
-    private final ASTExpression includedTemplateNameExp, encodingExp, ignoreMissingExp;
-    private final String encoding;
+    private final ASTExpression includedTemplateNameExp, ignoreMissingExp;
     private final Boolean ignoreMissingExpPrecalcedValue;
 
     /**
      * @param template the template that this <tt>#include</tt> is a part of.
      * @param includedTemplateNameExp the path of the template to be included.
-     * @param encodingExp the encoding to be used or null, if it's the default.
      */
     ASTDirInclude(Template template,
             ASTExpression includedTemplateNameExp,
-            ASTExpression encodingExp, ASTExpression ignoreMissingExp) throws ParseException {
+            ASTExpression ignoreMissingExp) throws ParseException {
         this.includedTemplateNameExp = includedTemplateNameExp;
-        
-        this.encodingExp = encodingExp;
-        if (encodingExp == null) {
-            encoding = null;
-        } else {
-            if (encodingExp.isLiteral()) {
-                try {
-                    TemplateModel tm = encodingExp.eval(null);
-                    if (!(tm instanceof TemplateScalarModel)) {
-                        throw new ParseException("Expected a string as the value of the \"encoding\" argument",
-                                encodingExp);
-                    }
-                    encoding = ((TemplateScalarModel) tm).getAsString();
-                } catch (TemplateException e) {
-                    // evaluation of literals must not throw a TemplateException
-                    throw new BugException(e);
-                }
-            } else {
-                encoding = null;
-            }
-        }
 
         this.ignoreMissingExp = ignoreMissingExp;
         if (ignoreMissingExp != null && ignoreMissingExp.isLiteral()) {
@@ -99,12 +73,6 @@ final class ASTDirInclude extends ASTDirective {
                     e.getMalformednessDescription());
         }
         
-        final String encoding = this.encoding != null
-                ? this.encoding
-                : (encodingExp != null
-                        ? encodingExp.evalAndCoerceToPlainText(env)
-                        : null);
-        
         final boolean ignoreMissing;
         if (ignoreMissingExpPrecalcedValue != null) {
             ignoreMissing = ignoreMissingExpPrecalcedValue.booleanValue();
@@ -116,7 +84,7 @@ final class ASTDirInclude extends ASTDirective {
         
         final Template includedTemplate;
         try {
-            includedTemplate = env.getTemplateForInclusion(fullIncludedTemplateName, encoding, ignoreMissing);
+            includedTemplate = env.getTemplateForInclusion(fullIncludedTemplateName, ignoreMissing);
         } catch (IOException e) {
             throw new _MiscTemplateException(e, env,
                     "Template inclusion failed (for parameter value ",
@@ -137,9 +105,6 @@ final class ASTDirInclude extends ASTDirective {
         buf.append(getNodeTypeSymbol());
         buf.append(' ');
         buf.append(includedTemplateNameExp.getCanonicalForm());
-        if (encodingExp != null) {
-            buf.append(" encoding=").append(encodingExp.getCanonicalForm());
-        }
         if (ignoreMissingExp != null) {
             buf.append(" ignore_missing=").append(ignoreMissingExp.getCanonicalForm());
         }
@@ -154,15 +119,14 @@ final class ASTDirInclude extends ASTDirective {
     
     @Override
     int getParameterCount() {
-        return 3;
+        return 2;
     }
 
     @Override
     Object getParameterValue(int idx) {
         switch (idx) {
         case 0: return includedTemplateNameExp;
-        case 1: return encodingExp;
-        case 2: return ignoreMissingExp;
+        case 1: return ignoreMissingExp;
         default: throw new IndexOutOfBoundsException();
         }
     }
@@ -171,8 +135,7 @@ final class ASTDirInclude extends ASTDirective {
     ParameterRole getParameterRole(int idx) {
         switch (idx) {
         case 0: return ParameterRole.TEMPLATE_NAME;
-        case 1: return ParameterRole.ENCODING_PARAMETER;
-        case 2: return ParameterRole.IGNORE_MISSING_PARAMETER;
+        case 1: return ParameterRole.IGNORE_MISSING_PARAMETER;
         default: throw new IndexOutOfBoundsException();
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/Configuration.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/Configuration.java b/src/main/java/org/apache/freemarker/core/Configuration.java
index e58ca5b..c5d290f 100644
--- a/src/main/java/org/apache/freemarker/core/Configuration.java
+++ b/src/main/java/org/apache/freemarker/core/Configuration.java
@@ -22,6 +22,7 @@ package org.apache.freemarker.core;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.Serializable;
 import java.text.SimpleDateFormat;
 import java.util.Collection;
 import java.util.Collections;
@@ -38,8 +39,6 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.TimeZone;
 import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 
 import org.apache.freemarker.core.model.ObjectWrapper;
 import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
@@ -439,8 +438,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
     private HashMap<String, Object> rewrappableSharedVariables = null;
     
     private String defaultEncoding = getDefaultDefaultEncoding();
-    private ConcurrentMap localeToCharsetMap = new ConcurrentHashMap();
-    
+
     /**
      * @deprecated Use {@link #Configuration(Version)} instead. Note that the version can be still modified later with
      *     {@link Configuration#setIncompatibleImprovements(Version)} (or
@@ -580,7 +578,6 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
         try {
             Configuration copy = (Configuration) super.clone();
             copy.sharedVariables = new HashMap(sharedVariables);
-            copy.localeToCharsetMap = new ConcurrentHashMap(localeToCharsetMap);
             copy.recreateTemplateResolverWith(
                     templateResolver.getTemplateLoader(), templateResolver.getCacheStorage(),
                     templateResolver.getTemplateLookupStrategy(), templateResolver.getTemplateNameFormat(),
@@ -598,112 +595,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
         sharedVariables.put("normalize_newlines", new NormalizeNewlines());
         sharedVariables.put("xml_escape", new XmlEscape());
     }
-    
-    /**
-     * Loads a preset language-to-encoding map, similarly as if you have called
-     * {@link #clearEncodingMap()} and then did multiple {@link #setEncoding(Locale, String)} calls.
-     * It assumes the usual character encodings for most languages.
-     * The previous content of the encoding map will be lost.
-     * This default map currently contains the following mappings:
-     * 
-     * <table style="width: auto; border-collapse: collapse" border="1" summary="preset language to encoding mapping">
-     *   <tr><td>ar</td><td>ISO-8859-6</td></tr>
-     *   <tr><td>be</td><td>ISO-8859-5</td></tr>
-     *   <tr><td>bg</td><td>ISO-8859-5</td></tr>
-     *   <tr><td>ca</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>cs</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>da</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>de</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>el</td><td>ISO-8859-7</td></tr>
-     *   <tr><td>en</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>es</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>et</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>fi</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>fr</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>hr</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>hu</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>is</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>it</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>iw</td><td>ISO-8859-8</td></tr>
-     *   <tr><td>ja</td><td>Shift_JIS</td></tr>
-     *   <tr><td>ko</td><td>EUC-KR</td></tr>    
-     *   <tr><td>lt</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>lv</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>mk</td><td>ISO-8859-5</td></tr>
-     *   <tr><td>nl</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>no</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>pl</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>pt</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>ro</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>ru</td><td>ISO-8859-5</td></tr>
-     *   <tr><td>sh</td><td>ISO-8859-5</td></tr>
-     *   <tr><td>sk</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>sl</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>sq</td><td>ISO-8859-2</td></tr>
-     *   <tr><td>sr</td><td>ISO-8859-5</td></tr>
-     *   <tr><td>sv</td><td>ISO-8859-1</td></tr>
-     *   <tr><td>tr</td><td>ISO-8859-9</td></tr>
-     *   <tr><td>uk</td><td>ISO-8859-5</td></tr>
-     *   <tr><td>zh</td><td>GB2312</td></tr>
-     *   <tr><td>zh_TW</td><td>Big5</td></tr>
-     * </table>
-     * 
-     * @see #clearEncodingMap()
-     * @see #setEncoding(Locale, String)
-     * @see #setDefaultEncoding(String)
-     */
-    public void loadBuiltInEncodingMap() {
-        localeToCharsetMap.clear();
-        localeToCharsetMap.put("ar", "ISO-8859-6");
-        localeToCharsetMap.put("be", "ISO-8859-5");
-        localeToCharsetMap.put("bg", "ISO-8859-5");
-        localeToCharsetMap.put("ca", "ISO-8859-1");
-        localeToCharsetMap.put("cs", "ISO-8859-2");
-        localeToCharsetMap.put("da", "ISO-8859-1");
-        localeToCharsetMap.put("de", "ISO-8859-1");
-        localeToCharsetMap.put("el", "ISO-8859-7");
-        localeToCharsetMap.put("en", "ISO-8859-1");
-        localeToCharsetMap.put("es", "ISO-8859-1");
-        localeToCharsetMap.put("et", "ISO-8859-1");
-        localeToCharsetMap.put("fi", "ISO-8859-1");
-        localeToCharsetMap.put("fr", "ISO-8859-1");
-        localeToCharsetMap.put("hr", "ISO-8859-2");
-        localeToCharsetMap.put("hu", "ISO-8859-2");
-        localeToCharsetMap.put("is", "ISO-8859-1");
-        localeToCharsetMap.put("it", "ISO-8859-1");
-        localeToCharsetMap.put("iw", "ISO-8859-8");
-        localeToCharsetMap.put("ja", "Shift_JIS");
-        localeToCharsetMap.put("ko", "EUC-KR");    
-        localeToCharsetMap.put("lt", "ISO-8859-2");
-        localeToCharsetMap.put("lv", "ISO-8859-2");
-        localeToCharsetMap.put("mk", "ISO-8859-5");
-        localeToCharsetMap.put("nl", "ISO-8859-1");
-        localeToCharsetMap.put("no", "ISO-8859-1");
-        localeToCharsetMap.put("pl", "ISO-8859-2");
-        localeToCharsetMap.put("pt", "ISO-8859-1");
-        localeToCharsetMap.put("ro", "ISO-8859-2");
-        localeToCharsetMap.put("ru", "ISO-8859-5");
-        localeToCharsetMap.put("sh", "ISO-8859-5");
-        localeToCharsetMap.put("sk", "ISO-8859-2");
-        localeToCharsetMap.put("sl", "ISO-8859-2");
-        localeToCharsetMap.put("sq", "ISO-8859-2");
-        localeToCharsetMap.put("sr", "ISO-8859-5");
-        localeToCharsetMap.put("sv", "ISO-8859-1");
-        localeToCharsetMap.put("tr", "ISO-8859-9");
-        localeToCharsetMap.put("uk", "ISO-8859-5");
-        localeToCharsetMap.put("zh", "GB2312");
-        localeToCharsetMap.put("zh_TW", "Big5");
-    }
-
-    /**
-     * Clears language-to-encoding map.
-     * @see #loadBuiltInEncodingMap
-     * @see #setEncoding
-     */
-    public void clearEncodingMap() {
-        localeToCharsetMap.clear();
-    }
-    
+
     /**
      * Sets a {@link TemplateLoader} that is used to look up and load templates;
      * as a side effect the template templateResolver will be emptied.
@@ -1894,53 +1786,44 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
      * missing/staled.
      * 
      * <p>
-     * This is a shorthand for {@link #getTemplate(String, Locale, Object, String, boolean)
-     * getTemplate(name, null, null, null, false)}; see more details there.
+     * This is a shorthand for {@link #getTemplate(String, Locale, Serializable, boolean)
+     * getTemplate(name, null, null, false)}; see more details there.
      * 
      * <p>
      * See {@link Configuration} for an example of basic usage.
      */
     public Template getTemplate(String name)
             throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
-        return getTemplate(name, null, null, null, false);
+        return getTemplate(name, null, null, false);
     }
 
     /**
-     * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean)
+     * Shorthand for {@link #getTemplate(String, Locale, Serializable, boolean)
      * getTemplate(name, locale, null, null, false)}.
      */
     public Template getTemplate(String name, Locale locale)
             throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
-        return getTemplate(name, locale, null, null, false);
+        return getTemplate(name, locale, null, false);
     }
 
     /**
-     * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean)
-     * getTemplate(name, null, null, encoding, false)}.
+     * Shorthand for {@link #getTemplate(String, Locale, Serializable, boolean)
+     * getTemplate(name, locale, customLookupCondition, false)}.
      */
-    public Template getTemplate(String name, String encoding)
+    public Template getTemplate(String name, Locale locale, Serializable customLookupCondition)
             throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
-        return getTemplate(name, null, null, encoding, false);
+        return getTemplate(name, locale, customLookupCondition, false);
     }
 
     /**
-     * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean)
-     * getTemplate(name, locale, null, encoding, false)}.
-     */
-    public Template getTemplate(String name, Locale locale, String encoding)
-            throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
-        return getTemplate(name, locale, null, encoding, false);
-    }
-
-    /**
-     * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean)
-     * getTemplate(name, locale, null, encoding, ignoreMissing)}.
+     * Shorthand for {@link #getTemplate(String, Locale, Serializable, boolean)
+     * getTemplate(name, locale, null, ignoreMissing)}.
      * 
      * @since 2.3.21
      */
-    public Template getTemplate(String name, Locale locale, String encoding, boolean ignoreMissing)
+    public Template getTemplate(String name, Locale locale, boolean ignoreMissing)
             throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
-        return getTemplate(name, locale, null, encoding, ignoreMissing);
+        return getTemplate(name, locale, null, ignoreMissing);
     }
     
     /**
@@ -1996,19 +1879,6 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
      *            custom {@link TemplateLookupStrategy}. See also:
      *            {@link TemplateLookupContext#getCustomLookupCondition()}.
      *
-     * @param encoding
-     *            Deprecated mechanism, {@code null} is the recommended; the charset used to interpret the template
-     *            source code bytes (if it's read from a binary source). Can be {@code null} since 2.3.22, in which case
-     *            it will default to {@link Configuration#getEncoding(Locale)} where {@code Locale} is the
-     *            {@code locale} parameter (when {@code locale} was {@code null} too, the its default value is used
-     *            instead). Why is this deprecated: It doesn't make sense to get the <em>same</em> template with
-     *            different encodings, hence, it's error prone to specify the encoding where you get the template.
-     *            Instead, if you have template "files" with different charsets, you should use
-     *            {@link #setTemplateConfigurations(TemplateConfigurationFactory)}, where you can associate encodings to
-     *            individual templates based on their names (like which "directory" are they in, what's their file
-     *            extension, etc.). The encoding associated with the templates that way overrides the encoding that you
-     *            specify here.
-     *
      * @param ignoreMissing
      *            If {@code true}, the method won't throw {@link TemplateNotFoundException} if the template doesn't
      *            exist, instead it returns {@code null}. Other kind of exceptions won't be suppressed.
@@ -2029,17 +1899,13 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
      * 
      * @since 2.3.22
      */
-    public Template getTemplate(String name, Locale locale, Object customLookupCondition,
-            String encoding, boolean ignoreMissing)
+    public Template getTemplate(String name, Locale locale, Serializable customLookupCondition, boolean
+            ignoreMissing)
             throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
         if (locale == null) {
             locale = getLocale();
         }
-        if (encoding == null) {
-            encoding = getEncoding(locale);
-        }
-        
-        final GetTemplateResult maybeTemp = templateResolver.getTemplate(name, locale, customLookupCondition, encoding);
+        final GetTemplateResult maybeTemp = templateResolver.getTemplate(name, locale, customLookupCondition);
         final Template temp = maybeTemp.getTemplate();
         if (temp == null) {
             if (ignoreMissing) {
@@ -2112,18 +1978,19 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
     }
 
     /**
-     * Sets the charset used for decoding byte sequences to character sequences when
-     * reading template files in a locale for which no explicit encoding
-     * was specified via {@link #setEncoding(Locale, String)}. Note that by default there is no locale specified for
-     * any locale, so the default encoding is always in effect.
-     * 
+     * Sets the charset used for decoding template files when there's no matching
+     * {@linkplain #getTemplateConfigurations() template configuration} that specifies
+     * the charset of the template.
+     *
+     * <p>Individual templates may specify their own charset by starting with
+     * <tt>&lt;#ftl encoding="..."&gt;</tt>. However, before that's detected, at least part of template must be
+     * decoded with some charset first, so this setting and {@linkplain #getTemplateConfigurations() template
+     * configuration} still has a role.
+     *
      * <p>Defaults to the default system encoding, which can change from one server to
      * another, so <b>you should always set this setting</b>. If you don't know what charset your should chose,
      * {@code "UTF-8"} is usually a good choice.
-     * 
-     * <p>Note that individual templates may specify their own charset by starting with
-     * <tt>&lt;#ftl encoding="..."&gt;</tt>
-     * 
+     *
      * @param encoding The name of the charset, such as {@code "UTF-8"} or {@code "ISO-8859-1"}
      */
     public void setDefaultEncoding(String encoding) {
@@ -2171,48 +2038,6 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
     }
 
     /**
-     * Gets the preferred character encoding for the given locale, or the 
-     * default encoding if no encoding is set explicitly for the specified
-     * locale. You can associate encodings with locales using 
-     * {@link #setEncoding(Locale, String)} or {@link #loadBuiltInEncodingMap()}.
-     */
-    public String getEncoding(Locale locale) {
-        if (localeToCharsetMap.isEmpty()) {
-            return defaultEncoding;
-        } else {
-            // Try for a full name match (may include country and variant)
-            String charset = (String) localeToCharsetMap.get(locale.toString());
-            if (charset == null) {
-                if (locale.getVariant().length() > 0) {
-                    Locale l = new Locale(locale.getLanguage(), locale.getCountry());
-                    charset = (String) localeToCharsetMap.get(l.toString());
-                    if (charset != null) {
-                        localeToCharsetMap.put(locale.toString(), charset);
-                    }
-                } 
-                charset = (String) localeToCharsetMap.get(locale.getLanguage());
-                if (charset != null) {
-                    localeToCharsetMap.put(locale.toString(), charset);
-                }
-            }
-            return charset != null ? charset : defaultEncoding;
-        }
-    }
-
-    /**
-     * Sets the character set encoding to use for templates of
-     * a given locale. If there is no explicit encoding set for some
-     * locale, then the default encoding will be used, what you can
-     * set with {@link #setDefaultEncoding}.
-     *
-     * @see #clearEncodingMap
-     * @see #loadBuiltInEncodingMap
-     */
-    public void setEncoding(Locale locale, String encoding) {
-        localeToCharsetMap.put(locale.toString(), encoding);
-    }
-
-    /**
      * Adds a shared variable to the configuration.
      * Shared sharedVariables are sharedVariables that are visible
      * as top-level sharedVariables for all templates which use this
@@ -2377,8 +2202,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
      * @since 2.3.19
      */
     public void removeTemplateFromCache(String name) throws IOException {
-        Locale loc = getLocale();
-        removeTemplateFromCache(name, loc, getEncoding(loc));
+        removeTemplateFromCache(name, getLocale());
     }
 
     /**
@@ -2386,15 +2210,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
      * @since 2.3.19
      */
     public void removeTemplateFromCache(String name, Locale locale) throws IOException {
-        removeTemplateFromCache(name, locale, getEncoding(locale));
-    }
-
-    /**
-     * Equivalent to <tt>removeTemplateFromCache(name, thisCfg.getLocale(), encoding, true)</tt>.
-     * @since 2.3.19
-     */
-    public void removeTemplateFromCache(String name, String encoding) throws IOException {
-        removeTemplateFromCache(name, getLocale(), encoding);
+        removeTemplateFromCache(name, locale, null);
     }
 
     /**
@@ -2404,14 +2220,15 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
      * alone does.
      * 
      * <p>For the meaning of the parameters, see
-     * {@link #getTemplate(String, Locale, String, boolean)}.
+     * {@link #getTemplate(String, Locale, Serializable, boolean)}.
      * 
      * <p>This method is thread-safe and can be called while the engine processes templates.
      * 
      * @since 2.3.19
      */
-    public void removeTemplateFromCache(String name, Locale locale, String encoding) throws IOException {
-        templateResolver.removeTemplateFromCache(name, locale, encoding);
+    public void removeTemplateFromCache(String name, Locale locale, Serializable customLookupCondition)
+            throws IOException {
+        templateResolver.removeTemplateFromCache(name, locale, customLookupCondition);
     }    
     
     /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/Environment.java b/src/main/java/org/apache/freemarker/core/Environment.java
index cac703d..7eac791 100644
--- a/src/main/java/org/apache/freemarker/core/Environment.java
+++ b/src/main/java/org/apache/freemarker/core/Environment.java
@@ -21,6 +21,7 @@ package org.apache.freemarker.core;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.io.Serializable;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.sql.Time;
@@ -2368,21 +2369,19 @@ public final class Environment extends Configurable {
      * separately call these two methods, so you can determine the source of exceptions more precisely, and thus achieve
      * more intelligent error handling.
      *
-     * @see #getTemplateForInclusion(String name, String encoding, boolean parse)
+     * @see #getTemplateForInclusion(String, boolean)
      * @see #include(Template includedTemplate)
      */
-    public void include(String name, String encoding, boolean parse)
-            throws IOException, TemplateException {
-        include(getTemplateForInclusion(name, encoding, parse));
+    public void include(String name, boolean parse) throws IOException, TemplateException {
+        include(getTemplateForInclusion(name, parse));
     }
 
     /**
-     * Same as {@link #getTemplateForInclusion(String, String, boolean)} with {@code false}
+     * Same as {@link #getTemplateForInclusion(String, boolean)} with {@code false}
      * {@code ignoreMissing} argument.
      */
-    public Template getTemplateForInclusion(String name, String encoding)
-            throws IOException {
-        return getTemplateForInclusion(name, encoding, false);
+    public Template getTemplateForInclusion(String name) throws IOException {
+        return getTemplateForInclusion(name, false);
     }
 
     /**
@@ -2396,54 +2395,34 @@ public final class Environment extends Configurable {
      *            currently executing template file). (Note that you can use
      *            {@link TemplateResolver#toRootBasedName(String, String)} to convert paths to template root based
      *            paths.) For more details see the identical parameter of
-     *            {@link Configuration#getTemplate(String, Locale, String, boolean)}
-     * 
-     * @param encoding
-     *            the charset of the obtained template. If {@code null}, the encoding of the top template that is
-     *            currently being processed in this {@link Environment} is used, which can lead to odd situations, so
-     *            using {@code null} is not recommended. In most applications, the value of
-     *            {@link Configuration#getEncoding(Locale)} (or {@link Configuration#getDefaultEncoding()}) should be
-     *            used here.
+     *            {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}
      *
      * @param ignoreMissing
-     *            See identical parameter of {@link Configuration#getTemplate(String, Locale, String, boolean)}
+     *            See identical parameter of {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}
      * 
-     * @return Same as {@link Configuration#getTemplate(String, Locale, String, boolean)}
+     * @return Same as {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}
      * @throws IOException
      *             Same as exceptions thrown by
-     *             {@link Configuration#getTemplate(String, Locale, String, boolean)}
+     *             {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}
      * 
      * @since 2.3.21
      */
-    public Template getTemplateForInclusion(String name, String encoding, boolean ignoreMissing)
+    public Template getTemplateForInclusion(String name, boolean ignoreMissing)
             throws IOException {
-        return configuration.getTemplate(
-                name, getLocale(), getIncludedTemplateCustomLookupCondition(),
-                encoding != null ? encoding : getIncludedTemplateEncoding(),
-                ignoreMissing);
+        return configuration.getTemplate(name, getLocale(), getIncludedTemplateCustomLookupCondition(), ignoreMissing);
     }
 
-    private Object getIncludedTemplateCustomLookupCondition() {
+    private Serializable getIncludedTemplateCustomLookupCondition() {
         return getCurrentTemplate().getCustomLookupCondition();
     }
 
-    private String getIncludedTemplateEncoding() {
-        String encoding;
-        // [FM3] This branch shouldn't exist, as it doesn't make much sense to inherit encoding. But we have to keep BC.
-        encoding = getCurrentTemplate().getEncoding();
-        if (encoding == null) {
-            encoding = configuration.getEncoding(getLocale());
-        }
-        return encoding;
-    }
-
     /**
      * Processes a Template in the context of this <code>Environment</code>, including its output in the
      * <code>Environment</code>'s Writer.
      *
      * @param includedTemplate
      *            the template to process. Note that it does <em>not</em> need to be a template returned by
-     *            {@link #getTemplateForInclusion(String name, String encoding, boolean parse)}.
+     *            {@link #getTemplateForInclusion(String, boolean)}.
      */
     public void include(Template includedTemplate)
             throws TemplateException, IOException {
@@ -2522,7 +2501,7 @@ public final class Environment extends Configurable {
      *            paths.)
      */
     public Template getTemplateForImporting(String name) throws IOException {
-        return getTemplateForInclusion(name, null, true);
+        return getTemplateForInclusion(name, true);
     }
 
     /**
@@ -2767,8 +2746,7 @@ public final class Environment extends Configurable {
         
         private final String templateName;
         private final Locale locale;
-        private final String encoding;
-        private final Object customLookupCondition;
+        private final Serializable customLookupCondition;
         
         private InitializationStatus status = InitializationStatus.UNINITIALIZED;
         
@@ -2782,7 +2760,6 @@ public final class Environment extends Configurable {
             this.templateName = templateName;
             // Make snapshot of all settings that influence template resolution:
             locale = getLocale();
-            encoding = getIncludedTemplateEncoding();
             customLookupCondition = getIncludedTemplateCustomLookupCondition();
         }
 
@@ -2821,9 +2798,7 @@ public final class Environment extends Configurable {
         }
 
         private void initialize() throws IOException, TemplateException {
-            setTemplate(configuration.getTemplate(
-                    templateName, locale, customLookupCondition, encoding,
-                    false));
+            setTemplate(configuration.getTemplate(templateName, locale, customLookupCondition, false));
             Locale lastLocale = getLocale();
             try {
                 setLocale(locale);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/ParameterRole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ParameterRole.java b/src/main/java/org/apache/freemarker/core/ParameterRole.java
index 1270b1c..146f0b8 100644
--- a/src/main/java/org/apache/freemarker/core/ParameterRole.java
+++ b/src/main/java/org/apache/freemarker/core/ParameterRole.java
@@ -52,7 +52,6 @@ final class ParameterRole {
     static final ParameterRole LIST_SOURCE = new ParameterRole("list source");
     static final ParameterRole TARGET_LOOP_VARIABLE = new ParameterRole("target loop variable");
     static final ParameterRole TEMPLATE_NAME = new ParameterRole("template name");
-    static final ParameterRole ENCODING_PARAMETER = new ParameterRole("\"encoding\" parameter");
     static final ParameterRole IGNORE_MISSING_PARAMETER = new ParameterRole("\"ignore_missing\" parameter");
     static final ParameterRole PARAMETER_NAME = new ParameterRole("parameter name");
     static final ParameterRole PARAMETER_DEFAULT = new ParameterRole("parameter default");

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/Template.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/Template.java b/src/main/java/org/apache/freemarker/core/Template.java
index 23096fe..e253197 100644
--- a/src/main/java/org/apache/freemarker/core/Template.java
+++ b/src/main/java/org/apache/freemarker/core/Template.java
@@ -26,6 +26,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
 import java.io.Reader;
+import java.io.Serializable;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.io.Writer;
@@ -34,6 +35,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Vector;
 
@@ -80,7 +82,7 @@ public class Template extends Configurable {
     private List imports = new Vector();
     private ASTElement rootElement;
     private String encoding, defaultNS;
-    private Object customLookupCondition;
+    private Serializable customLookupCondition;
     private int actualTagSyntax;
     private int actualNamingConvention;
     private boolean autoEscaping;
@@ -567,17 +569,16 @@ public class Template extends Configurable {
 
     /**
      * @param encoding
-     *            The encoding that was used to read this template. When this template {@code #include}-s or
-     *            {@code #import}-s another template, by default it will use this encoding for those. For backward
-     *            compatibility, this can be {@code null}, which will unset this setting.
+     *            The encoding that was used to read this template, or {@code null} if the source of the template
+     *            already gives back text (as opposed to binary data), so no decoding with a charset was needed.
      */
     void setEncoding(String encoding) {
         this.encoding = encoding;
     }
 
     /**
-     * Returns the default character encoding used for reading included/imported files; if {@code null}, then
-     * the encoding returned by {@link Configuration#getEncoding(java.util.Locale)} should be used instead.
+     * The encoding that was used to read this template, or {@code null} if the source of the template
+     * already gives back text (as opposed to binary data), so no decoding with a charset was needed.
      */
     public String getEncoding() {
         return encoding;
@@ -585,12 +586,10 @@ public class Template extends Configurable {
     
     /**
      * Gets the custom lookup condition with which this template was found. See the {@code customLookupCondition}
-     * parameter of {@link Configuration#getTemplate(String, java.util.Locale, Object, String, boolean)} for
-     * more explanation.
-     * 
-     * @since 2.3.22
+     * parameter of {@link Configuration#getTemplate(String, Locale, Serializable, boolean)} for more
+     * explanation.
      */
-    public Object getCustomLookupCondition() {
+    public Serializable getCustomLookupCondition() {
         return customLookupCondition;
     }
 
@@ -599,10 +598,8 @@ public class Template extends Configurable {
      * after instantiating the template with its constructor, after a successfull lookup that used this condition. So
      * this should only be called from code that deals with creating new {@code Template} objects, like from
      * {@link DefaultTemplateResolver}.
-     * 
-     * @since 2.3.22
      */
-    public void setCustomLookupCondition(Object customLookupCondition) {
+    public void setCustomLookupCondition(Serializable customLookupCondition) {
         this.customLookupCondition = customLookupCondition;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java b/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java
index 2e8c0f6..3d1b903 100644
--- a/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java
+++ b/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java
@@ -539,11 +539,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
 
     /**
      * 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.
+     * template "file", overriding everything but the encoding coming from the {@code #ftl} header.
      * 
      * <p>
      * If you are developing your own template loading/caching mechanism instead of the standard one, note that the

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java b/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java
index fced93f..37ba911 100644
--- a/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java
+++ b/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java
@@ -20,6 +20,7 @@
 package org.apache.freemarker.core;
 
 import java.io.FileNotFoundException;
+import java.io.Serializable;
 
 import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException;
 
@@ -54,7 +55,7 @@ public final class TemplateNotFoundException extends FileNotFoundException {
     /**
      * The custom lookup condition with which the template was requested, or {@code null} if there's no such condition.
      * See the {@code customLookupCondition} parameter of
-     * {@link Configuration#getTemplate(String, java.util.Locale, Object, String, boolean)}.
+     * {@link Configuration#getTemplate(String, java.util.Locale, Serializable, boolean)}.
      */
     public Object getCustomLookupCondition() {
         return customLookupCondition;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java b/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java
index 2260267..58c9ea9 100644
--- a/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java
@@ -18,12 +18,13 @@
  */
 package org.apache.freemarker.core.templateresolver;
 
+import java.io.Serializable;
 import java.util.Locale;
 
 import org.apache.freemarker.core.Template;
 
 /**
- * Used for the return value of {@link TemplateResolver#getTemplate(String, Locale, Object, String)}.
+ * Used for the return value of {@link TemplateResolver#getTemplate(String, Locale, Serializable)} .
  * 
  * @since 3.0.0
  */

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java
index 7d6f7a6..6bf1b1f 100644
--- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java
@@ -21,6 +21,7 @@ package org.apache.freemarker.core.templateresolver;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
+import java.io.Serializable;
 
 import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver;
 
@@ -28,7 +29,7 @@ import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver;
  * Stores shared state between {@link TemplateLoader} operations that are executed close to each other in the same
  * thread. For example, a {@link TemplateLoader} that reads from a database might wants to store the database
  * connection in it for reuse. The goal of sessions is mostly to increase performance. However, because a
- * {@link DefaultTemplateResolver#getTemplate(String, java.util.Locale, Object, String)} call is executed inside a single
+ * {@link DefaultTemplateResolver#getTemplate(String, java.util.Locale, Serializable)} call is executed inside a single
  * session, sessions can be also be utilized to ensure that the template lookup (see {@link TemplateLookupStrategy})
  * happens on a consistent view (a snapshot) of the backing storage, if the backing storage mechanism supports such
  * thing.

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java
index 3db956c..0a3b33a 100644
--- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java
@@ -92,7 +92,7 @@ public abstract class TemplateLookupContext<R extends TemplateLookupResult> {
 
     /**
      * Returns the value of the {@code customLookupCondition} parameter of
-     * {@link Configuration#getTemplate(String, Locale, Object, String, boolean)}; see requirements there, such
+     * {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}; see requirements there, such
      * as having a proper {@link Object#equals(Object)} and {@link Object#hashCode()} method. The interpretation of this
      * value is up to the custom {@link TemplateLookupStrategy}. Usually, it's used similarly to as the default lookup
      * strategy uses {@link #getTemplateLocale()}, that is, to look for a template variation that satisfies the

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java
index 1b04ba7..f257e2b 100644
--- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java
@@ -19,6 +19,7 @@
 package org.apache.freemarker.core.templateresolver;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.Locale;
 
 import org.apache.freemarker.core.Configuration;
@@ -62,7 +63,7 @@ public abstract class TemplateResolver {
      * 
      * <p>
      * All parameters must be non-{@code null}, except {@code customLookupCondition}. For the meaning of the parameters
-     * see {@link Configuration#getTemplate(String, Locale, String, boolean)}.
+     * see {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}.
      *
      * @return A {@link GetTemplateResult} object that contains the {@link Template}, or a
      *         {@link GetTemplateResult} object that contains {@code null} as the {@link Template} and information
@@ -82,8 +83,7 @@ public abstract class TemplateResolver {
      *             value.
      */
     // [FM3] This parameters will be removed: String encoding
-    public abstract GetTemplateResult getTemplate(String name, Locale locale, Object customLookupCondition,
-            String encoding)
+    public abstract GetTemplateResult getTemplate(String name, Locale locale, Serializable customLookupCondition)
             throws MalformedTemplateNameException, ParseException, IOException;
 
     /**
@@ -108,7 +108,7 @@ public abstract class TemplateResolver {
      * {@link Configuration#setTemplateUpdateDelayMilliseconds(long)} alone does.
      * 
      * <p>
-     * For the meaning of the parameters, see {@link #getTemplate(String, Locale, Object, String)}
+     * For the meaning of the parameters, see {@link #getTemplate(String, Locale, Serializable)}
      * 
      * <p>
      * This method is thread-safe and can be called while the engine processes templates.
@@ -116,7 +116,7 @@ public abstract class TemplateResolver {
      * @throws UnsupportedOperationException If the {@link TemplateResolver} implementation doesn't support this
      *        operation.
      */
-    public abstract void removeTemplateFromCache(String name, Locale locale, String encoding)
+    public abstract void removeTemplateFromCache(String name, Locale locale, Serializable customLookupCondition)
             throws IOException, UnsupportedOperationException;
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java b/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java
index 14d04f7..a5a574c 100644
--- a/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java
@@ -198,7 +198,7 @@ public class DefaultTemplateResolver extends TemplateResolver {
      * 
      * <p>
      * All parameters must be non-{@code null}, except {@code customLookupCondition}. For the meaning of the parameters
-     * see {@link Configuration#getTemplate(String, Locale, String, boolean)}.
+     * see {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}.
      *
      * @return A {@link GetTemplateResult} object that contains the {@link Template}, or a
      *         {@link GetTemplateResult} object that contains {@code null} as the {@link Template} and information
@@ -223,20 +223,18 @@ public class DefaultTemplateResolver extends TemplateResolver {
      * @since 2.3.22
      */
     @Override
-    public GetTemplateResult getTemplate(String name, Locale locale, Object customLookupCondition,
-            String encoding)
+    public GetTemplateResult getTemplate(String name, Locale locale, Serializable customLookupCondition)
     throws IOException {
         _NullArgumentException.check("name", name);
         _NullArgumentException.check("locale", locale);
-        _NullArgumentException.check("encoding", encoding);
-        
+
         name = templateNameFormat.normalizeRootBasedName(name);
         
         if (templateLoader == null) {
             return new GetTemplateResult(name, "The TemplateLoader (and TemplateLoader2) was null.");
         }
         
-        Template template = getTemplateInternal(name, locale, customLookupCondition, encoding);
+        Template template = getTemplateInternal(name, locale, customLookupCondition);
         return template != null ? new GetTemplateResult(template) : new GetTemplateResult(name, (String) null);
     }
 
@@ -251,14 +249,13 @@ public class DefaultTemplateResolver extends TemplateResolver {
     }
 
     private Template getTemplateInternal(
-            final String name, final Locale locale, final Object customLookupCondition,
-            final String encoding)
+            final String name, final Locale locale, final Serializable customLookupCondition)
     throws IOException {
         final boolean debug = LOG.isDebugEnabled();
         final String debugPrefix = debug
-                ? getDebugPrefix("getTemplate", name, locale, customLookupCondition, encoding)
+                ? getDebugPrefix("getTemplate", name, locale, customLookupCondition)
                 : null;
-        final CachedResultKey cacheKey = new CachedResultKey(name, locale, customLookupCondition, encoding);
+        final CachedResultKey cacheKey = new CachedResultKey(name, locale, customLookupCondition);
         
         CachedResult oldCachedResult = (CachedResult) cacheStorage.get(cacheKey);
         
@@ -387,8 +384,7 @@ public class DefaultTemplateResolver extends TemplateResolver {
             
             Template template = loadTemplate(
                     templateLoaderResult,
-                    name, newLookupResult.getTemplateSourceName(), locale, customLookupCondition,
-                    encoding);
+                    name, newLookupResult.getTemplateSourceName(), locale, customLookupCondition);
             if (session != null) {
                 session.close();
                 if (debug) {
@@ -524,8 +520,8 @@ public class DefaultTemplateResolver extends TemplateResolver {
     @SuppressWarnings("deprecation")
     private Template loadTemplate(
             TemplateLoadingResult templateLoaderResult,
-            final String name, final String sourceName, Locale locale, final Object customLookupCondition,
-            String initialEncoding) throws IOException {
+            final String name, final String sourceName, Locale locale, final Serializable customLookupCondition)
+            throws IOException {
         TemplateConfiguration tc;
         {
             TemplateConfiguration cfgTC;
@@ -552,23 +548,13 @@ public class DefaultTemplateResolver extends TemplateResolver {
             }
         }
 
-        TemplateLanguage templateLanguage = null;
-        if (tc != null) {
-            // TC.{encoding,locale} is stronger than the cfg.getTemplate arguments by design.
-            if (tc.isEncodingSet()) {
-                initialEncoding = tc.getEncoding();
-            }
-            if (tc.isLocaleSet()) {
-                locale = tc.getLocale();
-            }
-            if (tc.isTemplateLanguageSet()) {
-                templateLanguage = tc.getTemplateLanguage();
-            }
+        if (tc != null && tc.isLocaleSet()) {
+            locale = tc.getLocale();
         }
 
-        if (templateLanguage == null) {
-            templateLanguage = config.getTemplateLanguage();
-        }
+        String initialEncoding = tc != null && tc.isEncodingSet() ? tc.getEncoding() : config.getDefaultEncoding();
+        TemplateLanguage templateLanguage = tc != null && tc.isTemplateLanguageSet() ? tc.getTemplateLanguage()
+                : config .getTemplateLanguage();
 
         Template template;
         {
@@ -689,7 +675,7 @@ public class DefaultTemplateResolver extends TemplateResolver {
 
     /**
      * Removes all entries from the cache, forcing reloading of templates on subsequent
-     * {@link #getTemplate(String, Locale, Object, String)} calls.
+     * {@link #getTemplate(String, Locale, Serializable)} calls.
      * 
      * @param resetTemplateLoader
      *            Whether to call {@link TemplateLoader#resetState()}. on the template loader.
@@ -717,25 +703,16 @@ public class DefaultTemplateResolver extends TemplateResolver {
     }
 
     /**
-     * Same as {@link #removeTemplateFromCache(String, Locale, Object, String)} with {@code null}
-     * {@code customLookupCondition}.
-     */
-    @Override
-    public void removeTemplateFromCache(
-            String name, Locale locale, String encoding) throws IOException {
-        removeTemplateFromCache(name, locale, null, encoding);
-    }
-    
-    /**
      * Removes an entry from the cache, hence forcing the re-loading of it when it's next time requested. (It doesn't
      * delete the template file itself.) This is to give the application finer control over cache updating than
      * {@link #setTemplateUpdateDelayMilliseconds(long)} alone does.
      * 
      * For the meaning of the parameters, see
-     * {@link Configuration#getTemplate(String, Locale, Object, String, boolean)}
+     * {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}
      */
+    @Override
     public void removeTemplateFromCache(
-            String name, Locale locale, Object customLookupCondition, String encoding)
+            String name, Locale locale, Serializable customLookupCondition)
     throws IOException {
         if (name == null) {
             throw new IllegalArgumentException("Argument \"name\" can't be null");
@@ -743,16 +720,13 @@ public class DefaultTemplateResolver extends TemplateResolver {
         if (locale == null) {
             throw new IllegalArgumentException("Argument \"locale\" can't be null");
         }
-        if (encoding == null) {
-            throw new IllegalArgumentException("Argument \"encoding\" can't be null");
-        }
         name = templateNameFormat.normalizeRootBasedName(name);
         if (name != null && templateLoader != null) {
             boolean debug = LOG.isDebugEnabled();
             String debugPrefix = debug
-                    ? getDebugPrefix("removeTemplate", name, locale, customLookupCondition, encoding)
+                    ? getDebugPrefix("removeTemplate", name, locale, customLookupCondition)
                     : null;
-            CachedResultKey tk = new CachedResultKey(name, locale, customLookupCondition, encoding);
+            CachedResultKey tk = new CachedResultKey(name, locale, customLookupCondition);
             
             cacheStorage.remove(tk);
             if (debug) {
@@ -761,11 +735,10 @@ public class DefaultTemplateResolver extends TemplateResolver {
         }
     }
 
-    private String getDebugPrefix(String operation, String name, Locale locale, Object customLookupCondition, String encoding) {
+    private String getDebugPrefix(String operation, String name, Locale locale, Object customLookupCondition) {
         return operation + " " + _StringUtil.jQuoteNoXSS(name) + "("
                 + _StringUtil.jQuoteNoXSS(locale)
                 + (customLookupCondition != null ? ", cond=" + _StringUtil.jQuoteNoXSS(customLookupCondition) : "")
-                + ", " + encoding
                 + "): ";
     }    
 
@@ -813,41 +786,38 @@ public class DefaultTemplateResolver extends TemplateResolver {
     private static final class CachedResultKey implements Serializable {
         private final String name;
         private final Locale locale;
-        private final Object customLookupCondition;
-        private final String encoding;
+        private final Serializable customLookupCondition;
 
-        CachedResultKey(String name, Locale locale, Object customLookupCondition, String encoding) {
+        CachedResultKey(String name, Locale locale, Serializable customLookupCondition) {
             this.name = name;
             this.locale = locale;
             this.customLookupCondition = customLookupCondition;
-            this.encoding = encoding;
         }
 
         @Override
         public boolean equals(Object o) {
-            if (o instanceof CachedResultKey) {
-                CachedResultKey tk = (CachedResultKey) o;
-                return
+            if (!(o instanceof CachedResultKey)) {
+                return false;
+            }
+            CachedResultKey tk = (CachedResultKey) o;
+            return
                     name.equals(tk.name) &&
                     locale.equals(tk.locale) &&
-                    nullSafeEquals(customLookupCondition, tk.customLookupCondition) &&
-                    encoding.equals(tk.encoding);
-            }
-            return false;
+                    nullSafeEquals(customLookupCondition, tk.customLookupCondition);
         }
 
         @Override
         public int hashCode() {
-            return
-                name.hashCode() ^
-                locale.hashCode() ^
-                encoding.hashCode() ^
-                (customLookupCondition != null ? customLookupCondition.hashCode() : 0);
+            int result = name.hashCode();
+            result = 31 * result + locale.hashCode();
+            result = 31 * result + (customLookupCondition != null ? customLookupCondition.hashCode() : 0);
+            return result;
         }
+
     }
 
     /**
-     * Hold the a cached {@link #getTemplate(String, Locale, Object, String)} result and the associated
+     * Hold the a cached {@link #getTemplate(String, Locale, Serializable)} result and the associated
      * information needed to check if the cached value is up to date.
      * 
      * <p>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java b/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java
index cd0724a..0bb3c65 100644
--- a/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java
+++ b/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java
@@ -194,15 +194,11 @@ class JaxenXPathSupport implements XPathSupport {
     // [FM3] Look into this "hidden" feature
     static Template getTemplate(String systemId) throws IOException {
         Environment env = Environment.getCurrentEnvironment();
-        String encoding = env.getCurrentTemplate().getEncoding(); // [FM3] Encoding shouldn't be inherited anymore
-        if (encoding == null) {
-            encoding = env.getConfiguration().getEncoding(env.getLocale());
-        }
         String templatePath = env.getCurrentTemplate().getName();
         int lastSlash = templatePath.lastIndexOf('/');
         templatePath = lastSlash == -1 ? "" : templatePath.substring(0, lastSlash + 1);
         systemId = env.toFullTemplateName(templatePath, systemId);
-        return env.getConfiguration().getTemplate(systemId, env.getLocale(), encoding, false);
+        return env.getConfiguration().getTemplate(systemId, env.getLocale(), false);
     }
 
     private static InputSource createInputSource(String publicId, Template raw) throws IOException, SAXException {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java
index 0fc7cfa..0853133 100644
--- a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java
+++ b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java
@@ -205,8 +205,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  * that was the only way before Servlet 2.4), not via the more modern
  * {@link HttpServletResponse#setCharacterEncoding(String)} method. Note that the charset of a template usually comes
  * from {@link Configuration#getDefaultEncoding()} (i.e., from the {@code default_encoding} FreeMarker setting),
- * occasionally from {@link Configuration#getEncoding(Locale)} (when FreeMarker was configured to use different charsets
- * depending on the locale) or even more rarely from {@link Configuration#getTemplateConfigurations()} (when FreeMarker was
+ * or occasionally from {@link Configuration#getTemplateConfigurations()} (when FreeMarker was
  * configured to use a specific charset for certain templates).
  * <li>{@value #INIT_PARAM_VALUE_FROM_TEMPLATE}: This should be used in most applications, but it's not the default for
  * backward compatibility. It reads the {@link Configurable#getOutputEncoding()} setting of the template (note that the

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index 2566df6..ac20322 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -2935,7 +2935,7 @@ ASTDirInclude Include() :
 {
     ASTExpression nameExp;
     Token att, start, end;
-    ASTExpression exp, encodingExp = null, ignoreMissingExp = null;
+    ASTExpression exp, ignoreMissingExp = null;
 }
 {
     start = <_INCLUDE>
@@ -2947,16 +2947,14 @@ ASTDirInclude Include() :
         exp = ASTExpression()
         {
             String attString = att.image;
-            if (attString.equalsIgnoreCase("encoding")) {
-            	encodingExp = exp;
-            } else if (attString.equalsIgnoreCase("ignore_missing") || attString.equals("ignoreMissing")) {
+            if (attString.equalsIgnoreCase("ignore_missing") || attString.equals("ignoreMissing")) {
                 token_source.checkNamingConvention(att);
             	ignoreMissingExp = exp;
             } else {
                 String correctedName = attString.equals("ignoreMissing") ? "ignore_missing" : null;
                 throw new ParseException(
                 		"Unsupported named #include parameter: \"" + attString + "\". Supported parameters are: "
-                		+ "\"encoding\", \"ignore_missing\"."
+                		+ "\"ignore_missing\"."
                 		+ (correctedName == null
                 		      ? ""
                 		      : " Supporting camelCase parameter names is planned for FreeMarker 2.4.0; "
@@ -2968,7 +2966,7 @@ ASTDirInclude Include() :
     )*
     end = LooseDirectiveEnd()
     {
-        ASTDirInclude result = new ASTDirInclude(template, nameExp, encodingExp, ignoreMissingExp);
+        ASTDirInclude result = new ASTDirInclude(template, nameExp, ignoreMissingExp);
         result.setLocation(template, start, end);
         return result;
     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/manual/en_US/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/src/manual/en_US/FM3-CHANGE-LOG.txt b/src/manual/en_US/FM3-CHANGE-LOG.txt
index 6c7a5fb..5330a6a 100644
--- a/src/manual/en_US/FM3-CHANGE-LOG.txt
+++ b/src/manual/en_US/FM3-CHANGE-LOG.txt
@@ -133,7 +133,7 @@ the FreeMarer 3 changelog here:
     In FM2, such overloads has used the global static default DefaltObjectWrapper, but that was removed.
   - If the ObjectWrapper is not a DefaultObjectWrapper (or a subclass of it), `className?new(args)` will only accept 0 arguments.
     (Earlier we have fallen back to using the global static default DefaultObjectWrapper instance to handle argument unwrapping
-    and overloaded constructors.) Note that ?new is only used to instantiate TemplateModel-s, typically, tempalte language
+    and overloaded constructors.) Note that ?new is only used to instantiate TemplateModel-s, typically, template language
     functions/directives implemented in Java, and so they hardly ever has an argument.
   - FreemarkerServlet now requires that the ObjectWrapper it uses implements ObjectWrapperAndUnwrapper. (Thus, the return type
     of FreemarerServlet.createDefaultObjectWrapper() has changed to ObjectWrapperAndUnwrapper.) The unwrapping functionality is
@@ -156,9 +156,18 @@ the FreeMarer 3 changelog here:
 - Removed DefaultObjectWrapper.methodsShadowItems setting, in effect defaulting it to true. This has decided if the generic
   get method (`get(String)`) had priority over methods of similar name. The generic get method is only recognized from its
   name and parameter type, so it's a quite consfusing feature, and might will be removed alltogether.
-- DefaultObjectWrapper is not immutable (has no setter methods), and can only be constructed with DefaultObjectWrapper.Builder
+- DefaultObjectWrapper is now immutable (has no setter methods), and can only be constructed with DefaultObjectWrapper.Builder
 - Configuration.getTemplate has no "parse" parameter anymore. Similarly #include has no "parse" parameter anymore. Whether a
   template is parsed can be specified via Configuration.templateConfigurations, for example based on the file extension. Thus,
   a certain template is either always parsed or never parsed, and whoever gets or include it need not know about that.
-  Also added a new setting, "templateLanguge", which decides this; the two available values are
-  TemplateLanguage.FTL and TemplateLanguage.STATIC_TEXT.
\ No newline at end of file
+  Also added a new setting, "templateLanguage", which decides this; the two available values are
+  TemplateLanguage.FTL and TemplateLanguage.STATIC_TEXT.
+- Configuration.getTemplate has no "encoding" parameter anymore. Similarly #include has no "encoding" parameter either. The charset
+  of templates can be specified via Configuration.defaultEncoding and Configuration.templateConfigurations (for example based on the
+  directory it is in), or wirh the #ftl directive inside the template. Thus, a given template always has the same charset, no mater how
+  it's accessed.
+- #include-d/#import-ed templates don't inheirit the charset (encoding) of the #include-ing/#import-ing template. (Because,
+  again, the charset of a template file is independent of how you access it.)
+- Removed Configuration.setEncoding(java.util.Locale, String) and the related other methods. Because of the new logic of template
+  encodings, the locale to encoding mapping doesn't make much sense anymore.
+- Require customLookupCondition-s to be Serializable.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
index 51cdcc3..6539753 100644
--- a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
+++ b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
@@ -24,6 +24,7 @@ import static org.hamcrest.Matchers.*;
 import static org.junit.Assert.*;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.io.StringWriter;
 import java.lang.reflect.Field;
 import java.nio.charset.StandardCharsets;
@@ -51,6 +52,8 @@ import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
 import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat;
 import org.apache.freemarker.core.outputformat.impl.XMLOutputFormat;
 import org.apache.freemarker.core.templateresolver.CacheStorageWithGetSize;
+import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
 import org.apache.freemarker.core.templateresolver.TemplateLookupContext;
 import org.apache.freemarker.core.templateresolver.TemplateLookupResult;
 import org.apache.freemarker.core.templateresolver.TemplateLookupStrategy;
@@ -249,18 +252,25 @@ public class ConfigurationTest extends TestCase {
         final String latin2 = "ISO-8859-2";
         final String utf8 = "utf-8";
         final String tFtl = "t.ftl";
+        final String tHuFtl = "t_hu.ftl";
         final String tEnFtl = "t_en.ftl";
         final String tUtf8Ftl = "t-utf8.ftl";
-        final Integer custLookupCond = 123;
+        final Serializable custLookupCond = new Serializable() { };
         
         Configuration cfg = new Configuration(Configuration.VERSION_3_0_0);
         cfg.setLocale(Locale.GERMAN);
         cfg.setDefaultEncoding(latin1);
-        cfg.setEncoding(hu, latin2);
-        
+
+        TemplateConfiguration huTC = new TemplateConfiguration();
+        huTC.setEncoding(latin2);
+        cfg.setTemplateConfigurations(
+                new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*_hu.*"),
+                huTC));
+
         ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader();
         tl.putTemplate(tFtl, "${1}".getBytes(StandardCharsets.UTF_8));
         tl.putTemplate(tEnFtl, "${1}".getBytes(StandardCharsets.UTF_8));
+        tl.putTemplate(tHuFtl, "${1}".getBytes(StandardCharsets.UTF_8));
         tl.putTemplate(tUtf8Ftl, "<#ftl encoding='utf-8'>".getBytes(StandardCharsets.UTF_8));
         cfg.setTemplateLoader(tl);
         
@@ -282,7 +292,7 @@ public class ConfigurationTest extends TestCase {
             assertEquals(utf8, t.getEncoding());
         }
         
-        // 2 args overload 1:
+        // 2 args:
         {
             Template t = cfg.getTemplate(tFtl, Locale.GERMAN);
             assertEquals(tFtl, t.getName());
@@ -318,7 +328,7 @@ public class ConfigurationTest extends TestCase {
         {
             Template t = cfg.getTemplate(tFtl, hu);
             assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
+            assertEquals(tHuFtl, t.getSourceName());
             assertEquals(hu, t.getLocale());
             assertNull(t.getCustomLookupCondition());
             assertEquals(latin2, t.getEncoding());
@@ -331,55 +341,17 @@ public class ConfigurationTest extends TestCase {
             assertNull(t.getCustomLookupCondition());
             assertEquals(utf8, t.getEncoding());
         }
-        
-        // 2 args overload 2:
-        {
-            Template t = cfg.getTemplate(tFtl, utf8);
-            assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
-            assertEquals(Locale.GERMAN, t.getLocale());
-            assertNull(t.getCustomLookupCondition());
-            assertEquals(utf8, t.getEncoding());
-        }
-        {
-            Template t = cfg.getTemplate(tFtl, (String) null);
-            assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
-            assertEquals(Locale.GERMAN, t.getLocale());
-            assertNull(t.getCustomLookupCondition());
-            assertEquals(latin1, t.getEncoding());
-        }
-        
+
         // 3 args:
-        {
-            Template t = cfg.getTemplate(tFtl, hu, utf8);
-            assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
-            assertEquals(hu, t.getLocale());
-            assertNull(t.getCustomLookupCondition());
-            assertEquals(utf8, t.getEncoding());
-            assertOutputEquals("1", t);
-        }
-        {
-            Template t = cfg.getTemplate(tFtl, hu, null);
-            assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
-            assertEquals(hu, t.getLocale());
-            assertNull(t.getCustomLookupCondition());
-            assertEquals(latin2, t.getEncoding());
-            assertOutputEquals("1", t);
-        }
-        {
-            Template t = cfg.getTemplate(tFtl, null, utf8);
-            assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
-            assertEquals(Locale.GERMAN, t.getLocale());
-            assertNull(t.getCustomLookupCondition());
-            assertEquals(utf8, t.getEncoding());
-            assertOutputEquals("1", t);
+        try {
+            cfg.getTemplate("missing.ftl", hu, false);
+            fail();
+        } catch (TemplateNotFoundException e) {
+            // Expected
         }
+        assertNull(cfg.getTemplate("missing.ftl", hu, true));
         {
-            Template t = cfg.getTemplate(tFtl, null, null);
+            Template t = cfg.getTemplate(tFtl, null, true);
             assertEquals(tFtl, t.getName());
             assertEquals(tFtl, t.getSourceName());
             assertEquals(Locale.GERMAN, t.getLocale());
@@ -387,80 +359,42 @@ public class ConfigurationTest extends TestCase {
             assertEquals(latin1, t.getEncoding());
             assertOutputEquals("1", t);
         }
-        
-        // 4 args:
         {
-            Template t = cfg.getTemplate(tFtl, hu, utf8, true);
+            Template t = cfg.getTemplate(tFtl, hu, true);
             assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
-            assertEquals(hu, t.getLocale());
-            assertNull(t.getCustomLookupCondition());
-            assertEquals(utf8, t.getEncoding());
-            assertOutputEquals("1", t);
-        }
-        {
-            Template t = cfg.getTemplate(tFtl, null, utf8, true);
-            assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
-            assertEquals(Locale.GERMAN, t.getLocale());
-            assertNull(t.getCustomLookupCondition());
-            assertEquals(utf8, t.getEncoding());
-            assertOutputEquals("1", t);
-        }
-        {
-            Template t = cfg.getTemplate(tFtl, hu, null, true);
-            assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
+            assertEquals(tHuFtl, t.getSourceName());
             assertEquals(hu, t.getLocale());
             assertNull(t.getCustomLookupCondition());
             assertEquals(latin2, t.getEncoding());
             assertOutputEquals("1", t);
         }
 
-        // Ignore missing
+        // 4 args:
         try {
-            cfg.getTemplate("missing.ftl", hu, utf8, false);
+            cfg.getTemplate("missing.ftl", hu, custLookupCond, false);
             fail();
         } catch (TemplateNotFoundException e) {
             // Expected
         }
-        assertNull(cfg.getTemplate("missing.ftl", hu, utf8, true));
-        
-        // 5 args:
+        assertNull(cfg.getTemplate("missing.ftl", hu, custLookupCond, true));
         {
-            Template t = cfg.getTemplate(tFtl, hu, custLookupCond, utf8, false);
+            Template t = cfg.getTemplate(tFtl, hu, custLookupCond, false);
             assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
+            assertEquals(tHuFtl, t.getSourceName());
             assertEquals(hu, t.getLocale());
             assertEquals(custLookupCond, t.getCustomLookupCondition());
-            assertEquals(utf8, t.getEncoding());
+            assertEquals(latin2, t.getEncoding());
             assertOutputEquals("1", t);
         }
         {
-            Template t = cfg.getTemplate(tFtl, null, custLookupCond, utf8, false);
+            Template t = cfg.getTemplate(tFtl, null, custLookupCond, false);
             assertEquals(tFtl, t.getName());
             assertEquals(tFtl, t.getSourceName());
             assertEquals(Locale.GERMAN, t.getLocale());
             assertEquals(custLookupCond, t.getCustomLookupCondition());
-            assertEquals(utf8, t.getEncoding());
-            assertOutputEquals("1", t);
-        }
-        {
-            Template t = cfg.getTemplate(tFtl, hu, custLookupCond, null, false);
-            assertEquals(tFtl, t.getName());
-            assertEquals(tFtl, t.getSourceName());
-            assertEquals(hu, t.getLocale());
-            assertEquals(custLookupCond, t.getCustomLookupCondition());
-            assertEquals(latin2, t.getEncoding());
+            assertEquals(latin1, t.getEncoding());
             assertOutputEquals("1", t);
         }
-        try {
-            cfg.getTemplate("missing.ftl", hu, custLookupCond, utf8, false);
-            fail();
-        } catch (TemplateNotFoundException e) {
-            // Expected
-        }
-        assertNull(cfg.getTemplate("missing.ftl", hu, custLookupCond, utf8, true));
     }
 
     private void assertOutputEquals(final String expectedContent, final Template t) throws ConfigurationException,

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java b/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java
deleted file mode 100644
index 60ba865..0000000
--- a/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java
+++ /dev/null
@@ -1,87 +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;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
-import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
-import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.StrongCacheStorage;
-import org.junit.Test;
-
-public class TemplatGetEncodingTest {
-
-    @Test
-    public void test() throws IOException {
-        Configuration cfg = new Configuration(Configuration.VERSION_3_0_0);
-        {
-            cfg.setDefaultEncoding("ISO-8859-2");
-            ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader();
-            tl.putTemplate("t", "test".getBytes(StandardCharsets.UTF_8));
-            tl.putTemplate("static", "<#test>".getBytes(StandardCharsets.UTF_8));
-            TemplateConfiguration staticTextTC = new TemplateConfiguration();
-            staticTextTC.setTemplateLanguage(TemplateLanguage.STATIC_TEXT);
-            cfg.setTemplateConfigurations(
-                    new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("static"), staticTextTC));
-            cfg.setTemplateLoader(tl);
-            cfg.setCacheStorage(new StrongCacheStorage());
-        }
-
-        {
-            Template tDefEnc = cfg.getTemplate("t");
-            assertEquals("ISO-8859-2", tDefEnc.getEncoding());
-            assertSame(tDefEnc, cfg.getTemplate("t"));
-
-            Template tDefEnc2 = cfg.getTemplate("t", (String) null);
-            assertEquals("ISO-8859-2", tDefEnc2.getEncoding());
-            assertSame(tDefEnc, tDefEnc2);
-            
-            Template tUTF8 = cfg.getTemplate("t", "UTF-8");
-            assertEquals("UTF-8", tUTF8.getEncoding());
-            assertSame(tUTF8, cfg.getTemplate("t", "UTF-8"));
-            assertNotSame(tDefEnc, tUTF8);
-        }
-
-        {
-            Template tDefEnc = cfg.getTemplate("static", null, null, false);
-            assertEquals("ISO-8859-2", tDefEnc.getEncoding());
-            assertSame(tDefEnc, cfg.getTemplate("static", null, null, false));
-
-            Template tUTF8 = cfg.getTemplate("static", null, "UTF-8", false);
-            assertEquals("UTF-8", tUTF8.getEncoding());
-            assertSame(tUTF8, cfg.getTemplate("static", null, "UTF-8", false));
-            assertNotSame(tDefEnc, tUTF8);
-        }
-        
-        {
-            Template nonStoredT = new Template(null, "test", cfg);
-            assertNull(nonStoredT.getEncoding());
-        }
-
-        {
-            Template nonStoredT = Template.createPlainTextTemplate(null, "<#test>", cfg);
-            assertNull(nonStoredT.getEncoding());
-        }
-    }
-
-}