http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/Configuration.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/Configuration.java 
b/src/main/java/freemarker/template/Configuration.java
deleted file mode 100644
index b2f9b0e..0000000
--- a/src/main/java/freemarker/template/Configuration.java
+++ /dev/null
@@ -1,3189 +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 freemarker.template;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLConnection;
-import java.text.DecimalFormat;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import freemarker.cache.CacheStorage;
-import freemarker.cache.ClassTemplateLoader;
-import freemarker.cache.FileTemplateLoader;
-import freemarker.cache.MruCacheStorage;
-import freemarker.cache.MultiTemplateLoader;
-import freemarker.cache.SoftCacheStorage;
-import freemarker.cache.TemplateCache;
-import freemarker.cache.TemplateCache.MaybeMissingTemplate;
-import freemarker.cache.TemplateConfigurationFactory;
-import freemarker.cache.TemplateLoader;
-import freemarker.cache.TemplateLookupContext;
-import freemarker.cache.TemplateLookupStrategy;
-import freemarker.cache.TemplateNameFormat;
-import freemarker.cache.URLTemplateLoader;
-import freemarker.core.BugException;
-import freemarker.core.CSSOutputFormat;
-import freemarker.core.CombinedMarkupOutputFormat;
-import freemarker.core.Configurable;
-import freemarker.core.Environment;
-import freemarker.core.HTMLOutputFormat;
-import freemarker.core.JSONOutputFormat;
-import freemarker.core.JavaScriptOutputFormat;
-import freemarker.core.MarkupOutputFormat;
-import freemarker.core.OutputFormat;
-import freemarker.core.ParseException;
-import freemarker.core.ParserConfiguration;
-import freemarker.core.PlainTextOutputFormat;
-import freemarker.core.RTFOutputFormat;
-import freemarker.core.TemplateConfiguration;
-import freemarker.core.TemplateMarkupOutputModel;
-import freemarker.core.UndefinedOutputFormat;
-import freemarker.core.UnregisteredOutputFormatException;
-import freemarker.core.XHTMLOutputFormat;
-import freemarker.core.XMLOutputFormat;
-import freemarker.core._CoreAPI;
-import freemarker.core._DelayedJQuote;
-import freemarker.core._MiscTemplateException;
-import freemarker.core._ObjectBuilderSettingEvaluator;
-import freemarker.core._SettingEvaluationEnvironment;
-import freemarker.core._SortedArraySet;
-import freemarker.core._UnmodifiableCompositeSet;
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.beans.BeansWrapperBuilder;
-import freemarker.template.utility.CaptureOutput;
-import freemarker.template.utility.ClassUtil;
-import freemarker.template.utility.Constants;
-import freemarker.template.utility.HtmlEscape;
-import freemarker.template.utility.NormalizeNewlines;
-import freemarker.template.utility.NullArgumentException;
-import freemarker.template.utility.SecurityUtilities;
-import freemarker.template.utility.StandardCompress;
-import freemarker.template.utility.StringUtil;
-import freemarker.template.utility.XmlEscape;
-
-/**
- * <b>The main entry point into the FreeMarker API</b>; encapsulates the 
configuration settings of FreeMarker,
- * also serves as a central template-loading and caching service.
- *
- * <p>This class is meant to be used in a singleton pattern. That is, you 
create an instance of this at the beginning of
- * the application life-cycle, set its {@link #setSetting(String, String) 
configuration settings} there (either with the
- * setter methods like {@link #setTemplateLoader(TemplateLoader)} or by 
loading a {@code .properties} file), and then
- * use that single instance everywhere in your application. Frequently 
re-creating {@link Configuration} is a typical
- * and grave mistake from performance standpoint, as the {@link Configuration} 
holds the template cache, and often also
- * the class introspection cache, which then will be lost. (Note that, 
naturally, having multiple long-lived instances,
- * like one per component that internally uses FreeMarker is fine.)  
- * 
- * <p>The basic usage pattern is like:
- * 
- * <pre>
- *  // Where the application is initialized; in general you do this ONLY ONCE 
in the application life-cycle!
- *  Configuration cfg = new Configuration(VERSION_<i>X</i>_<i>Y</i>_<i>Z</i>));
- *  // Where X, Y, Z enables the not-100%-backward-compatible fixes introduced 
in
- *  // FreeMarker version X.Y.Z  and earlier (see {@link 
#Configuration(Version)}).
- *  cfg.set<i>SomeSetting</i>(...);
- *  cfg.set<i>OtherSetting</i>(...);
- *  ...
- *  
- *  // Later, whenever the application needs a template (so you may do this a 
lot, and from multiple threads):
- *  {@link Template Template} myTemplate = cfg.{@link #getTemplate(String) 
getTemplate}("myTemplate.html");
- *  myTemplate.{@link Template#process(Object, java.io.Writer) 
process}(dataModel, out);</pre>
- * 
- * <p>A couple of settings that you should not leave on its default value are:
- * <ul>
- *   <li>{@link #setTemplateLoader(TemplateLoader) template_loader}: The 
default value is deprecated and in fact quite
- *       useless. (For the most common cases you can use the convenience 
methods,
- *       {@link #setDirectoryForTemplateLoading(File)} and {@link 
#setClassForTemplateLoading(Class, String)} and
- *       {@link #setClassLoaderForTemplateLoading(ClassLoader, String)} too.)
- *   <li>{@link #setDefaultEncoding(String) default_encoding}: The default 
value is system dependent, which makes it
- *       fragile on servers, so it should be set explicitly, like to "UTF-8" 
nowadays. 
- *   <li>{@link #setTemplateExceptionHandler(TemplateExceptionHandler) 
template_exception_handler}: For developing
- *       HTML pages, the most convenient value is {@link 
TemplateExceptionHandler#HTML_DEBUG_HANDLER}. For production,
- *       {@link TemplateExceptionHandler#RETHROW_HANDLER} is safer to use.
- *   <!-- 2.4: recommend the new object wrapper here -->
- * </ul>
- * 
- * <p>A {@link Configuration} object is thread-safe only after you have 
stopped modifying the configuration settings,
- * and you have <b>safely published</b> it (see JSR 133 and related 
literature) to other threads. Generally, you set
- * everything directly after you have instantiated the {@link Configuration} 
object, then you don't change the settings
- * anymore, so then it's safe to make it accessible (again, via a "safe 
publication" technique) from multiple threads.
- * The methods that aren't for modifying settings, like {@link 
#getTemplate(String)}, are thread-safe.
- */
-public class Configuration extends Configurable implements Cloneable, 
ParserConfiguration {
-    
-    private static final Logger LOG = 
LoggerFactory.getLogger("freemarker.cache");
-    
-    private static final String VERSION_PROPERTIES_PATH = 
"freemarker/version.properties";
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String DEFAULT_ENCODING_KEY_SNAKE_CASE = 
"default_encoding"; 
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String DEFAULT_ENCODING_KEY_CAMEL_CASE = 
"defaultEncoding"; 
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String DEFAULT_ENCODING_KEY = 
DEFAULT_ENCODING_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String LOCALIZED_LOOKUP_KEY_SNAKE_CASE = 
"localized_lookup";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String LOCALIZED_LOOKUP_KEY_CAMEL_CASE = 
"localizedLookup";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String LOCALIZED_LOOKUP_KEY = 
LOCALIZED_LOOKUP_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String WHITESPACE_STRIPPING_KEY_SNAKE_CASE = 
"whitespace_stripping";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String WHITESPACE_STRIPPING_KEY_CAMEL_CASE = 
"whitespaceStripping";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String WHITESPACE_STRIPPING_KEY = 
WHITESPACE_STRIPPING_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.24 */
-    public static final String OUTPUT_FORMAT_KEY_SNAKE_CASE = "output_format";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.24 */
-    public static final String OUTPUT_FORMAT_KEY_CAMEL_CASE = "outputFormat";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String OUTPUT_FORMAT_KEY = 
OUTPUT_FORMAT_KEY_SNAKE_CASE;
-
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.24 */
-    public static final String 
RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE = 
"recognize_standard_file_extensions";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.24 */
-    public static final String 
RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE = 
"recognizeStandardFileExtensions";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY
-            = RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.24 */
-    public static final String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE 
= "registered_custom_output_formats";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.24 */
-    public static final String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE 
= "registeredCustomOutputFormats";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY = 
REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE;
-
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.24 */
-    public static final String AUTO_ESCAPING_POLICY_KEY_SNAKE_CASE = 
"auto_escaping_policy";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.24 */
-    public static final String AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE = 
"autoEscapingPolicy";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String AUTO_ESCAPING_POLICY_KEY = 
AUTO_ESCAPING_POLICY_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String CACHE_STORAGE_KEY_SNAKE_CASE = "cache_storage";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String CACHE_STORAGE_KEY_CAMEL_CASE = "cacheStorage";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String CACHE_STORAGE_KEY = 
CACHE_STORAGE_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TEMPLATE_UPDATE_DELAY_KEY_SNAKE_CASE = 
"template_update_delay";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TEMPLATE_UPDATE_DELAY_KEY_CAMEL_CASE = 
"templateUpdateDelay";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String TEMPLATE_UPDATE_DELAY_KEY = 
TEMPLATE_UPDATE_DELAY_KEY_SNAKE_CASE;
-    
-    /**
-     * Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23
-     * @deprecated Use {@link Configurable#AUTO_IMPORT_KEY_SNAKE_CASE} instead.
-     */
-    @Deprecated
-    public static final String AUTO_IMPORT_KEY_SNAKE_CASE = "auto_import";
-    /**
-     * Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23
-     * @deprecated Use {@link Configurable#AUTO_IMPORT_KEY_CAMEL_CASE} instead.
-     */
-    @Deprecated
-    public static final String AUTO_IMPORT_KEY_CAMEL_CASE = "autoImport";
-    /**
-     * Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints.
-     * @deprecated Use {@link Configurable#AUTO_IMPORT_KEY_SNAKE_CASE} instead.
-     */
-    @Deprecated
-    public static final String AUTO_IMPORT_KEY = AUTO_IMPORT_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String AUTO_INCLUDE_KEY_SNAKE_CASE = "auto_include";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String AUTO_INCLUDE_KEY_CAMEL_CASE = "autoInclude";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String AUTO_INCLUDE_KEY = AUTO_INCLUDE_KEY_SNAKE_CASE;
-
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TAG_SYNTAX_KEY_SNAKE_CASE = "tag_syntax";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TAG_SYNTAX_KEY_CAMEL_CASE = "tagSyntax";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String TAG_SYNTAX_KEY = TAG_SYNTAX_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String NAMING_CONVENTION_KEY_SNAKE_CASE = 
"naming_convention";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String NAMING_CONVENTION_KEY_CAMEL_CASE = 
"namingConvention";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String NAMING_CONVENTION_KEY = 
NAMING_CONVENTION_KEY_SNAKE_CASE;
-
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.25 */
-    public static final String TAB_SIZE_KEY_SNAKE_CASE = "tab_size";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.25 */
-    public static final String TAB_SIZE_KEY_CAMEL_CASE = "tabSize";
-    /** Alias to the {@code ..._SNAKE_CASE} variation. @since 2.3.25 */
-    public static final String TAB_SIZE_KEY = TAB_SIZE_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TEMPLATE_LOADER_KEY_SNAKE_CASE = 
"template_loader";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TEMPLATE_LOADER_KEY_CAMEL_CASE = 
"templateLoader";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String TEMPLATE_LOADER_KEY = 
TEMPLATE_LOADER_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TEMPLATE_LOOKUP_STRATEGY_KEY_SNAKE_CASE = 
"template_lookup_strategy";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TEMPLATE_LOOKUP_STRATEGY_KEY_CAMEL_CASE = 
"templateLookupStrategy";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String TEMPLATE_LOOKUP_STRATEGY_KEY = 
TEMPLATE_LOOKUP_STRATEGY_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TEMPLATE_NAME_FORMAT_KEY_SNAKE_CASE = 
"template_name_format";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String TEMPLATE_NAME_FORMAT_KEY_CAMEL_CASE = 
"templateNameFormat";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String TEMPLATE_NAME_FORMAT_KEY = 
TEMPLATE_NAME_FORMAT_KEY_SNAKE_CASE;
-
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.24 */
-    public static final String TEMPLATE_CONFIGURATIONS_KEY_SNAKE_CASE = 
"template_configurations";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.24 */
-    public static final String TEMPLATE_CONFIGURATIONS_KEY_CAMEL_CASE = 
"templateConfigurations";
-    /** Alias to the {@code ..._SNAKE_CASE} variation. @since 2.3.24 */
-    public static final String TEMPLATE_CONFIGURATIONS_KEY = 
TEMPLATE_CONFIGURATIONS_KEY_SNAKE_CASE;
-    
-    /** Legacy, snake case ({@code like_this}) variation of the setting name. 
@since 2.3.23 */
-    public static final String INCOMPATIBLE_IMPROVEMENTS_KEY_SNAKE_CASE = 
"incompatible_improvements";
-    /** Modern, camel case ({@code likeThis}) variation of the setting name. 
@since 2.3.23 */
-    public static final String INCOMPATIBLE_IMPROVEMENTS_KEY_CAMEL_CASE = 
"incompatibleImprovements";
-    /** Alias to the {@code ..._SNAKE_CASE} variation due to backward 
compatibility constraints. */
-    public static final String INCOMPATIBLE_IMPROVEMENTS_KEY = 
INCOMPATIBLE_IMPROVEMENTS_KEY_SNAKE_CASE;
-    
-    /** @deprecated Use {@link #INCOMPATIBLE_IMPROVEMENTS_KEY} instead. */
-    @Deprecated
-    public static final String INCOMPATIBLE_IMPROVEMENTS = 
INCOMPATIBLE_IMPROVEMENTS_KEY_SNAKE_CASE;
-    /** @deprecated Use {@link #INCOMPATIBLE_IMPROVEMENTS_KEY} instead. */
-    @Deprecated
-    public static final String INCOMPATIBLE_ENHANCEMENTS = 
"incompatible_enhancements";
-    
-    private static final String[] SETTING_NAMES_SNAKE_CASE = new String[] {
-        // Must be sorted alphabetically!
-        AUTO_ESCAPING_POLICY_KEY_SNAKE_CASE,
-        CACHE_STORAGE_KEY_SNAKE_CASE,
-        DEFAULT_ENCODING_KEY_SNAKE_CASE,
-        INCOMPATIBLE_IMPROVEMENTS_KEY_SNAKE_CASE,
-        LOCALIZED_LOOKUP_KEY_SNAKE_CASE,
-        NAMING_CONVENTION_KEY_SNAKE_CASE,
-        OUTPUT_FORMAT_KEY_SNAKE_CASE,
-        RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE,
-        REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE,
-        TAB_SIZE_KEY_SNAKE_CASE,
-        TAG_SYNTAX_KEY_SNAKE_CASE,
-        TEMPLATE_CONFIGURATIONS_KEY_SNAKE_CASE,
-        TEMPLATE_LOADER_KEY_SNAKE_CASE,
-        TEMPLATE_LOOKUP_STRATEGY_KEY_SNAKE_CASE,
-        TEMPLATE_NAME_FORMAT_KEY_SNAKE_CASE,
-        TEMPLATE_UPDATE_DELAY_KEY_SNAKE_CASE,
-        WHITESPACE_STRIPPING_KEY_SNAKE_CASE,
-    };
-
-    private static final String[] SETTING_NAMES_CAMEL_CASE = new String[] {
-        // Must be sorted alphabetically!
-        AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE,
-        CACHE_STORAGE_KEY_CAMEL_CASE,
-        DEFAULT_ENCODING_KEY_CAMEL_CASE,
-        INCOMPATIBLE_IMPROVEMENTS_KEY_CAMEL_CASE,
-        LOCALIZED_LOOKUP_KEY_CAMEL_CASE,
-        NAMING_CONVENTION_KEY_CAMEL_CASE,
-        OUTPUT_FORMAT_KEY_CAMEL_CASE,
-        RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE,
-        REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE,
-        TAB_SIZE_KEY_CAMEL_CASE,
-        TAG_SYNTAX_KEY_CAMEL_CASE,
-        TEMPLATE_CONFIGURATIONS_KEY_CAMEL_CASE,
-        TEMPLATE_LOADER_KEY_CAMEL_CASE,
-        TEMPLATE_LOOKUP_STRATEGY_KEY_CAMEL_CASE,
-        TEMPLATE_NAME_FORMAT_KEY_CAMEL_CASE,
-        TEMPLATE_UPDATE_DELAY_KEY_CAMEL_CASE,
-        WHITESPACE_STRIPPING_KEY_CAMEL_CASE
-    };
-    
-    private static final Map<String, OutputFormat> STANDARD_OUTPUT_FORMATS;
-    static {
-        STANDARD_OUTPUT_FORMATS = new HashMap<String, OutputFormat>();
-        STANDARD_OUTPUT_FORMATS.put(UndefinedOutputFormat.INSTANCE.getName(), 
UndefinedOutputFormat.INSTANCE);
-        STANDARD_OUTPUT_FORMATS.put(HTMLOutputFormat.INSTANCE.getName(), 
HTMLOutputFormat.INSTANCE);
-        STANDARD_OUTPUT_FORMATS.put(XHTMLOutputFormat.INSTANCE.getName(), 
XHTMLOutputFormat.INSTANCE);
-        STANDARD_OUTPUT_FORMATS.put(XMLOutputFormat.INSTANCE.getName(), 
XMLOutputFormat.INSTANCE);
-        STANDARD_OUTPUT_FORMATS.put(RTFOutputFormat.INSTANCE.getName(), 
RTFOutputFormat.INSTANCE);
-        STANDARD_OUTPUT_FORMATS.put(PlainTextOutputFormat.INSTANCE.getName(), 
PlainTextOutputFormat.INSTANCE);
-        STANDARD_OUTPUT_FORMATS.put(CSSOutputFormat.INSTANCE.getName(), 
CSSOutputFormat.INSTANCE);
-        STANDARD_OUTPUT_FORMATS.put(JavaScriptOutputFormat.INSTANCE.getName(), 
JavaScriptOutputFormat.INSTANCE);
-        STANDARD_OUTPUT_FORMATS.put(JSONOutputFormat.INSTANCE.getName(), 
JSONOutputFormat.INSTANCE);
-    }
-    
-    public static final int AUTO_DETECT_TAG_SYNTAX = 0;
-    public static final int ANGLE_BRACKET_TAG_SYNTAX = 1;
-    public static final int SQUARE_BRACKET_TAG_SYNTAX = 2;
-
-    public static final int AUTO_DETECT_NAMING_CONVENTION = 10;
-    public static final int LEGACY_NAMING_CONVENTION = 11;
-    public static final int CAMEL_CASE_NAMING_CONVENTION = 12;
-
-    /**
-     * Don't enable auto-escaping, regardless of what the {@link OutputFormat} 
is. Note that a {@code 
-     * <#ftl auto_esc=true>} in the template will override this.
-     */
-    public static final int DISABLE_AUTO_ESCAPING_POLICY = 20;
-    /**
-     * Enable auto-escaping if the output format supports it and {@link 
MarkupOutputFormat#isAutoEscapedByDefault()} is
-     * {@code true}.
-     */
-    public static final int ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY = 21;
-    /** Enable auto-escaping if the {@link OutputFormat} supports it. */
-    public static final int ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY = 22;
-    
-    /** FreeMarker version 2.3.0 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_0 = new Version(2, 3, 0);
-    
-    /** FreeMarker version 2.3.19 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_19 = new Version(2, 3, 19);
-    
-    /** FreeMarker version 2.3.20 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_20 = new Version(2, 3, 20);
-    
-    /** FreeMarker version 2.3.21 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_21 = new Version(2, 3, 21);
-
-    /** FreeMarker version 2.3.22 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_22 = new Version(2, 3, 22);
-
-    /** FreeMarker version 2.3.23 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_23 = new Version(2, 3, 23);
-
-    /** FreeMarker version 2.3.24 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_24 = new Version(2, 3, 24);
-
-    /** FreeMarker version 2.3.25 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_25 = new Version(2, 3, 25);
-
-    /** FreeMarker version 2.3.26 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_2_3_26 = new Version(2, 3, 26);
-    
-    /** FreeMarker version 3.0.0 (an {@link #Configuration(Version) 
incompatible improvements break-point}) */
-    public static final Version VERSION_3_0_0 = new Version(3, 0, 0);
-    
-    /** The default of {@link #getIncompatibleImprovements()}, currently 
{@link #VERSION_2_3_0}. */
-    public static final Version DEFAULT_INCOMPATIBLE_IMPROVEMENTS = 
Configuration.VERSION_2_3_0;
-    /** @deprecated Use {@link #DEFAULT_INCOMPATIBLE_IMPROVEMENTS} instead. */
-    @Deprecated
-    public static final String DEFAULT_INCOMPATIBLE_ENHANCEMENTS = 
DEFAULT_INCOMPATIBLE_IMPROVEMENTS.toString();
-    /** @deprecated Use {@link #DEFAULT_INCOMPATIBLE_IMPROVEMENTS} instead. */
-    @Deprecated
-    public static final int PARSED_DEFAULT_INCOMPATIBLE_ENHANCEMENTS = 
DEFAULT_INCOMPATIBLE_IMPROVEMENTS.intValue(); 
-    
-    private static final String NULL = "null";
-    private static final String DEFAULT = "default";
-    
-    private static final Version VERSION;
-    static {
-        try {
-            Properties vp = new Properties();
-            InputStream ins = Configuration.class.getClassLoader()
-                    .getResourceAsStream(VERSION_PROPERTIES_PATH);
-            if (ins == null) {
-                throw new RuntimeException("Version file is missing.");
-            } else {
-                try {
-                    vp.load(ins);
-                } finally {
-                    ins.close();
-                }
-                
-                String versionString  = getRequiredVersionProperty(vp, 
"version");
-                
-                Date buildDate;
-                {
-                    String buildDateStr = getRequiredVersionProperty(vp, 
"buildTimestamp");
-                    if (buildDateStr.endsWith("Z")) {
-                        buildDateStr = buildDateStr.substring(0, 
buildDateStr.length() - 1) + "+0000";
-                    }
-                    try {
-                        buildDate = new 
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US).parse(buildDateStr);
-                    } catch (java.text.ParseException e) {
-                        buildDate = null;
-                    }
-                }
-                
-                final Boolean gaeCompliant = 
Boolean.valueOf(getRequiredVersionProperty(vp, "isGAECompliant"));
-                
-                VERSION = new Version(versionString, gaeCompliant, buildDate);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to load and parse " + 
VERSION_PROPERTIES_PATH, e);
-        }
-    }
-    
-    private static final String FM_24_DETECTION_CLASS_NAME = 
"freemarker.core._2_4_OrLaterMarker";
-    private static final boolean FM_24_DETECTED;
-    static {
-        boolean fm24detected;
-        try {
-            Class.forName(FM_24_DETECTION_CLASS_NAME);
-            fm24detected = true;
-        } catch (ClassNotFoundException e) {
-            fm24detected = false;
-        } catch (LinkageError e) {
-            fm24detected = true;
-        } catch (Throwable e) {
-            // Unexpected. We assume that there's no clash.
-            fm24detected = false;
-        }
-        FM_24_DETECTED = fm24detected;
-    }
-    
-    private final static Object defaultConfigLock = new Object();
-
-    private static volatile Configuration defaultConfig;
-
-    private volatile boolean localizedLookup = true;
-    private boolean whitespaceStripping = true;
-    private int autoEscapingPolicy = ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY;
-    private OutputFormat outputFormat = UndefinedOutputFormat.INSTANCE;
-    private boolean outputFormatExplicitlySet;
-    private Boolean recognizeStandardFileExtensions;
-    private Map<String, ? extends OutputFormat> registeredCustomOutputFormats 
= Collections.emptyMap(); 
-    private Version incompatibleImprovements;
-    private int tagSyntax = ANGLE_BRACKET_TAG_SYNTAX;
-    private int namingConvention = AUTO_DETECT_NAMING_CONVENTION;
-    private int tabSize = 8;  // Default from JavaCC 3.x 
-
-    private TemplateCache cache;
-    
-    private boolean templateLoaderExplicitlySet;
-    private boolean templateLookupStrategyExplicitlySet;
-    private boolean templateNameFormatExplicitlySet;
-    private boolean cacheStorageExplicitlySet;
-    
-    private boolean objectWrapperExplicitlySet;
-    private boolean templateExceptionHandlerExplicitlySet;
-    private boolean logTemplateExceptionsExplicitlySet;
-    
-    private HashMap/*<String, TemplateModel>*/ sharedVariables = new HashMap();
-
-    /**
-     * Needed so that it doesn't mater in what order do you call {@link 
#setSharedVaribles(Map)}
-     * and {@link #setObjectWrapper(ObjectWrapper)}. When the user configures 
FreeMarker from Spring XML, he has no
-     * control over the order, so it has to work on both ways.
-     */
-    private HashMap/*<String, Object>*/ rewrappableSharedVariables = null;
-    
-    private String defaultEncoding = 
SecurityUtilities.getSystemProperty("file.encoding", "utf-8");
-    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
-     *     {@link Configuration#setSettings(Properties)}).  
-     */
-    @Deprecated
-    public Configuration() {
-        this(DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
-    }
-
-    /**
-     * Creates a new instance and sets which of the non-backward-compatible 
bugfixes/improvements should be enabled.
-     * Note that the specified versions corresponds to the {@code 
incompatible_improvements} configuration setting, and
-     * can be changed later, with {@link 
#setIncompatibleImprovements(Version)} for example. 
-     *
-     * <p><b>About the "incompatible improvements" setting</b>
-     *
-     * <p>This setting value is the FreeMarker version number where the not 
100% backward compatible bug fixes and
-     * improvements that you want to enable were already implemented. In new 
projects you should set this to the
-     * FreeMarker version that you are actually using. In older projects it's 
also usually better to keep this high,
-     * however you better check the changes activated (find them below), at 
least if not only the 3rd version number
-     * (the micro version) of {@code incompatibleImprovements} is increased. 
Generally, as far as you only increase the
-     * last version number of this setting, the changes are always low risk. 
The default value is 2.3.0 to maximize
-     * backward compatibility, but that value isn't recommended.
-     * 
-     * <p>Bugfixes and improvements that are fully backward compatible, also 
those that are important security fixes,
-     * are enabled regardless of the incompatible improvements setting.
-     * 
-     * <p>An important consequence of setting this setting is that now your 
application will check if the stated minimum
-     * FreeMarker version requirement is met. Like if you set this setting to 
2.3.22, but accidentally the application
-     * is deployed with FreeMarker 2.3.21, then FreeMarker will fail, telling 
that a higher version is required. After
-     * all, the fixes/improvements you have requested aren't available on a 
lower version.
-     * 
-     * <p>Note that as FreeMarker's minor (2nd) or major (1st) version number 
increments, it's possible that emulating
-     * some of the old bugs will become unsupported, that is, even if you set 
this setting to a low value, it silently
-     * wont bring back the old behavior anymore. Information about that will 
be present here.
-     * 
-     * <p>Currently the effects of this setting are:
-     * <ul>
-     *   <li><p>
-     *     2.3.0: This is the lowest supported value, the version used in 
older projects. This is the default in the
-     *     FreeMarker 2.3.x series.
-     *   </li>
-     *   <li><p>
-     *     2.3.19 (or higher): Bug fix: Wrong {@code #} tags were printed as 
static text instead of
-     *     causing parsing error when there was no correct {@code #} or {@code 
@} tag earlier in the
-     *     same template.
-     *   </li>
-     *   <li><p>
-     *     2.3.20 (or higher): {@code ?html} will escape apostrophe-quotes 
just like {@code ?xhtml} does. Utilizing
-     *     this is highly recommended, because otherwise if interpolations are 
used inside attribute values that use
-     *     apostrophe-quotation (<tt>&lt;foo bar='${val}'&gt;</tt>) instead of 
plain quotation mark
-     *     (<tt>&lt;foo bar="${val}"&gt;</tt>), they might produce HTML/XML 
that's not well-formed. Note that
-     *     {@code ?html} didn't do this because long ago there was no 
cross-browser way of doing this, but it's not a
-     *     concern anymore.
-     *   </li>
-     *   <li><p>
-     *     2.3.21 (or higher):
-     *     <ul>
-     *       <li><p>
-     *         The <em>default</em> of the {@code object_wrapper} setting 
({@link #getObjectWrapper()}) changes from
-     *         {@link ObjectWrapper#DEFAULT_WRAPPER} to another almost 
identical {@link DefaultObjectWrapper} singleton,
-     *         returned by {@link DefaultObjectWrapperBuilder#build()}. The 
new default object wrapper's
-     *         "incompatible improvements" version is set to the same as of 
the {@link Configuration}.
-     *         See {@link BeansWrapper#BeansWrapper(Version)} for further 
details. Furthermore, the new default
-     *         object wrapper doesn't allow changing its settings; setter 
methods throw {@link IllegalStateException}).
-     *         (If anything tries to call setters on the old default in your 
application, that's a dangerous bug that
-     *         won't remain hidden now. As the old default is a singleton too, 
potentially shared by independently
-     *         developed components, most of them expects the out-of-the-box 
behavior from it (and the others are
-     *         necessarily buggy). Also, then concurrency glitches can occur 
(and even pollute the class introspection
-     *         cache) because the singleton is modified after publishing to 
other threads.)
-     *         Furthermore the new default object wrapper shares class 
introspection cache with other
-     *         {@link BeansWrapper}-s created with {@link 
BeansWrapperBuilder}, which has an impact as
-     *         {@link BeansWrapper#clearClassIntrospecitonCache()} will be 
disallowed; see more about it there.
-     *       </li>
-     *       <li><p>
-     *          The {@code ?iso_...} built-ins won't show the time zone offset 
for {@link java.sql.Time} values anymore,
-     *          because most databases store time values that aren't in any 
time zone, but just store hour, minute,
-     *          second, and decimal second field values. If you still want to 
show the offset (like for PostgreSQL
-     *          "time with time zone" columns you should), you can force 
showing the time zone offset by using
-     *          {@code myTime?string.iso_fz} (and its other variants).
-     *       </li>
-     *       <li><p>{@code ?is_enumerable} correctly returns {@code false} for 
Java methods get from Java objects that
-     *         are wrapped with {@link BeansWrapper} and its subclasses, like 
{@link DefaultObjectWrapper}. Although
-     *         method values implement {@link TemplateSequenceModel} (because 
of a historical design quirk in
-     *         {@link BeansWrapper}), trying to {@code #list} them will cause 
error, hence they aren't enumerable.
-     *       </li>
-     *       <li><p>
-     *          {@code ?c} will return {@code "INF"}, {@code "-INF"} and 
{@code "NaN"} for positive/negative infinity
-     *          and IEEE floating point Not-a-Number, respectively. These are 
the XML Schema compatible representations
-     *          of these special values. Earlier it has returned what {@link 
DecimalFormat} did with US locale, none of
-     *          which was understood by any (common) computer language.
-     *       </li>
-     *       <li><p>
-     *          FTL hash literals that repeat keys now only have the key once 
with {@code ?keys}, and only has the last
-     *          value associated to that key with {@code ?values}. This is 
consistent with the behavior of
-     *          {@code hash[key]} and how maps work in Java.       
-     *       </li>
-     *       <li><p>In most cases (where FreeMarker is able to do that), for 
{@link TemplateLoader}-s that use
-     *         {@link URLConnection}, {@code 
URLConnection#setUseCaches(boolean)} will called with {@code false},
-     *         so that only FreeMarker will do caching, not the URL scheme's 
handler.
-     *         See {@link 
URLTemplateLoader#setURLConnectionUsesCaches(Boolean)} for more details.
-     *       </li>
-     *       <li><p>
-     *         The default of the {@code template_loader} setting ({@link 
Configuration#getTemplateLoader()}) changes
-     *         to {@code null}, which means that FreeMarker will not find any 
templates. Earlier
-     *         the default was a {@link FileTemplateLoader} that used the 
current directory as the root. This was
-     *         dangerous and fragile as you usually don't have good control 
over what the current directory will be.
-     *         Luckily, the old default almost never looked for the templates 
at the right place
-     *         anyway, so pretty much all applications had to set the {@code 
template_loader} setting, so it's unlikely
-     *         that changing the default breaks your application.
-     *       </li>
-     *       <li><p>
-     *          Right-unlimited ranges become readable (like listable), so 
{@code <#list 1.. as i>...</#list>} works.
-     *          Earlier they were only usable for slicing (like {@code 
hits[10..]}).
-     *       </li>
-     *       <li><p>
-     *          Empty ranges return {@link Constants#EMPTY_SEQUENCE} instead 
of an empty {@link SimpleSequence}. This
-     *          is in theory backward compatible, as the API only promises to 
give something that implements
-     *          {@link TemplateSequenceModel}.
-     *       </li>
-     *       <li><p>
-     *          Unclosed comments ({@code <#-- ...}) and {@code #noparse}-s 
won't be silently closed at the end of
-     *          template anymore, but cause a parsing error instead.
-     *       </li>
-     *     </ul>
-     *   </li>
-     *   <li><p>
-     *     2.3.22 (or higher):
-     *     <ul>
-     *       <li><p>
-     *          {@link DefaultObjectWrapper} has some substantial changes with 
{@code incompatibleImprovements} 2.3.22;
-     *          check them out at {@link 
DefaultObjectWrapper#DefaultObjectWrapper(Version)}. It's important to know
-     *          that if you set the {@code object_wrapper} setting (to an 
other value than {@code "default"}), rather
-     *          than leaving it on its default value, the {@code 
object_wrapper} won't inherit the
-     *          {@code incompatibleImprovements} of the {@link Configuration}. 
In that case, if you want the 2.3.22
-     *          improvements of {@link DefaultObjectWrapper}, you have to set 
it in the {@link DefaultObjectWrapper}
-     *          object itself too! (Note that it's OK to use a {@link 
DefaultObjectWrapper} with a different
-     *          {@code incompatibleImprovements} version number than that of 
the {@link Configuration}, if that's
-     *          really what you want.)
-     *       </li>
-     *       <li><p>
-     *          In templates, {@code .template_name} will <em>always</em> 
return the main (top level) template's name.
-     *          It won't be affected by {@code #include} and {@code #nested} 
anymore. This is unintended, a bug with
-     *          {@code incompatible_improvement} 2.3.22 (a consequence of the 
lower level fixing described in the next
-     *          point). The old behavior of {@code .template_name} is restored 
if you set
-     *          {@code incompatible_improvement} to 2.3.23 (while {@link 
Configurable#getParent()}) of
-     *          {@link Environment} keeps the changed behavior shown in the 
next point). 
-     *       </li>
-     *       <li><p>
-     *          {@code #include} and {@code #nested} doesn't change the parent 
{@link Template} (see
-     *          {@link Configurable#getParent()}) of the {@link Environment} 
anymore to the {@link Template} that's
-     *          included or whose namespace {@code #nested} "returns" to. 
Thus, the parent of {@link Environment} will
-     *          be now always the main {@link Template}. (The main {@link 
Template} is the {@link Template} whose
-     *          {@code process} or {@code createProcessingEnvironment} method 
was called to initiate the output
-     *          generation.) Note that apart from the effect on FTL's {@code 
.template_name} (see
-     *          previous point), this should only matter if you have set 
settings directly on {@link Template} objects,
-     *          and almost nobody does that. Also note that macro calls have 
never changed the {@link Environment}
-     *          parent to the {@link Template} that contains the macro 
definition, so this mechanism was always broken.
-     *          As now we consistently never change the parent, the behavior 
when calling macros didn't change.
-     *       </li>
-     *       <li><p>
-     *          When using {@code freemarker.ext.servlet.FreemarkerServlet}:
-     *          <ul>
-     *             <li>
-     *               <p>When using custom JSP tag libraries: Fixes bug where 
some kind of
-     *               values, when put into the JSP <em>page</em> scope (via 
{@code #global} or via the JSP
-     *               {@code PageContext} API) and later read back with the JSP 
{@code PageContext} API (typically in a
-     *               custom JSP tag), might come back as FreeMarker {@link 
TemplateModel} objects instead of as objects
-     *               with a standard Java type. Other Servlet scopes aren't 
affected. It's highly unlikely that
-     *               something expects the presence of this bug. The affected 
values are of the FTL types listed below,
-     *               and to trigger the bug, they either had to be created 
directly in the template (like as an FTL
-     *               literal or with {@code ?date}/{@code time}/{@code 
datetime}), or you had to use
-     *               {@link DefaultObjectWrapper} or {@link 
SimpleObjectWrapper} (or a subclass of them):
-     *               
-     *               <ul>
-     *                 <li>FTL date/time/date-time values may came back as 
{@link SimpleDate}-s, now they come back as
-     *                 {@link java.util.Date java.util.Date}-s instead.</li>
-     *             
-     *                 <li>FTL sequence values may came back as {@link 
SimpleSequence}-s, now they come back as
-     *                 {@link java.util.List}-s as expected. This at least 
stands assuming that the
-     *                 {@link Configuration#setSetting(String, String) 
object_wrapper} configuration setting is a
-     *                 subclass of {@link BeansWrapper} (such as {@link 
DefaultObjectWrapper}, which is the default),
-     *                 but that's practically always the case in applications 
that use FreeMarker's JSP extension
-     *                 (otherwise it can still work, but it depends on the 
quality and capabilities of the
-     *                 {@link ObjectWrapper} implementation).</li>
-     *             
-     *                 <li>FTL hash values may came back as {@link 
SimpleHash}-es, now they come back as
-     *                 {@link java.util.Map}-s as expected (again, assuming 
that the object wrapper is a subclass of
-     *                 {@link BeansWrapper}, like preferably {@link 
DefaultObjectWrapper}, which is also the default).
-     *                 </li>
-     *             
-     *                 <li>FTL collection values may came back as {@link 
SimpleCollection}-s, now they come back as
-     *                 {@link java.util.Collection}-s as expected (again, 
assuming that the object wrapper is a subclass
-     *                 of {@link BeansWrapper}, like preferably {@link 
DefaultObjectWrapper}).</li>
-     *               </ul>
-     *             </li>
-     *             <li><p>
-     *               Initial {@code "["} in the {@code TemplatePath} init-param
-     *               has special meaning; it's used for specifying multiple 
comma separated locations, like in
-     *               {@code <param-value>[ WEB-INF/templates, 
classpath:com/example/myapp/templates ]</param-value>}
-     *             </li>
-     *             <li><p>
-     *               Initial <tt>"{"</tt> in the {@code TemplatePath} 
init-param is reserved for future purposes, and
-     *               thus will throw exception.
-     *             </li>
-     *          </ul>
-     *       </li>
-     *     </ul>
-     *   </li>
-     *   <li><p>
-     *     2.3.23 (or higher):
-     *     <ul>
-     *       <li><p>
-     *          Fixed a loophole in the implementation of the long existing 
parse-time rule that says that
-     *          {@code #break}, in the FTL source code itself, must occur 
nested inside a breakable directive, such as
-     *          {@code #list} or {@code #switch}. This check could be 
circumvented with {@code #macro} or
-     *          {@code #function}, like this:
-     *          {@code <#list 1..1 as x><#macro 
callMeLater><#break></#macro></#list><@callMeLater />}.
-     *          After activating this fix, this will be a parse time error.
-     *       </li>
-     *       <li><p>
-     *          If you have used {@code incompatible_improvements} 2.3.22 
earlier, know that there the behavior of the
-     *          {@code .template_name} special variable used in templates was 
accidentally altered, but now it's
-     *          restored to be backward compatible with 2.3.0. (Ironically, 
the restored legacy behavior itself is
-     *          broken when it comes to macro invocations, we just keep it for 
backward compatibility. If you need fixed
-     *          behavior, use {@code .current_template_name} or {@code 
.main_template_name} instead.)
-     *       </li>
-     *     </ul>
-     *   </li>
-     *   <li><p>
-     *     2.3.24 (or higher):
-     *     <ul>
-     *       <li><p>
-     *          The default of the
-     *          {@link #setRecognizeStandardFileExtensions(boolean) 
recognize_standard_file_extensions}
-     *          setting changes to {@code true}, which means that templates 
whose name ends with {@code ".ftlh"} or
-     *          {@code ".ftlx"} will automatically get {@link 
HTMLOutputFormat#INSTANCE} or
-     *          {@link XMLOutputFormat#INSTANCE} output format respectively, 
in both cases with
-     *          {@link #ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY} {@link 
#setAutoEscapingPolicy(int) auto_escaping_policy}.
-     *          These "file" extensions aren't case sensitive.
-     *       </li>
-     *       <li><p>
-     *          In number format and date format strings (like in the {@code 
number_format} setting, or in templates in
-     *          {@code n?string("0.##")}), an initial {@code '@'} has special 
meaning; they refer to a custom format
-     *          with the name given after the {@code @} (see: {@link 
#setCustomNumberFormats(Map)},
-     *          {@link #setCustomDateFormats(Map)}, {@link 
#setNumberFormat(String)}, and {@link #setDateTimeFormat}).
-     *          If the custom format doesn't exist, that will be an error. To 
have a literal {@code @} as the first
-     *          character in the output, it has to be written as {@code @@}. 
Again, all this only applies to the very
-     *          first character of the format string, so {@code @} characters 
elsewhere must not be doubled. Also, if
-     *          there are any custom formats defined, initial {@code '@'} will 
have the new meaning regardless of
-     *          the value of the {@code incompatible_improvements} setting. So 
you don't need to set the
-     *          {@code incompatible_improvements} only to use custom formats. 
-     *       </li>
-     *       <li><p>
-     *          Expressions inside interpolations that were inside <em>string 
literal expressions</em>
-     *          (not <code>${...}</code>-s in general), like in 
<code>&lt;#assign s="Hello ${name}!"&gt;</code>, has
-     *          always used {@code incompatbileImprovement}-s 0 (2.3.0 in 
effect). Now it's fixed.
-     *       </li>
-     *       <li><p>
-     *          {@link DefaultObjectWrapper} has some minor changes with 
{@code incompatibleImprovements} 2.3.24;
-     *          check them out at {@link 
DefaultObjectWrapper#DefaultObjectWrapper(Version)}. It's important to know
-     *          that if you set the {@code object_wrapper} setting (to an 
other value than {@code "default"}), rather
-     *          than leaving it on its default value, the {@code 
object_wrapper} won't inherit the
-     *          {@code incompatibleImprovements} of the {@link Configuration}. 
In that case, if you want the 2.3.24
-     *          improvements of {@link DefaultObjectWrapper}, you have to set 
it in the {@link DefaultObjectWrapper}
-     *          object itself too! (Note that it's OK to use a {@link 
DefaultObjectWrapper} with a different
-     *          {@code incompatibleImprovements} version number than that of 
the {@link Configuration}, if that's
-     *          really what you want.)
-     *       </li>
-     *       <li><p>
-     *          Fixed bug: The {@code #import} directive meant to copy the 
library variable into a global variable if
-     *          it's executed in the main namespace, but that haven't happened 
when the imported template was already
-     *          imported earlier in another namespace. 
-     *       </li>
-     *       <li><p>
-     *          {@code ?is_sequence} doesn't return {@code true} for Java 
methods wrapped by {@link BeansWrapper} and
-     *          its subclasses (most notably {@link DefaultObjectWrapper}) 
anymore, as they only implement the
-     *          {@code [index]} operator, but not {@code ?size}, which causes 
{@code <#list ...>} to fail among others.
-     *          (They shouldn't implement either, but this is historical 
heritage.)
-     *     </ul>
-     *   </li>
-     *   <li><p>
-     *     2.3.25 (or higher):
-     *     <ul>
-     *       <li><p>
-     *          When calling {@link Configurable#setAutoIncludes(List)} on a 
{@link Configuration}, it filters out
-     *          duplicates from the list, similarly as repeatedly calling 
{@link Configurable#addAutoInclude(String)}
-     *          would, hence avoiding repeated inclusions. Calling {@link 
Configurable#setAutoIncludes(List)} on other
-     *          {@link Configurable}-s always do this filtering regardless of 
the incompatible improvements setting. 
-     *     </ul>
-     *   </li>
-     * </ul>
-     * 
-     * @throws IllegalArgumentException
-     *             If {@code incompatibleImmprovements} refers to a version 
that wasn't released yet when the currently
-     *             used FreeMarker version was released, or is less than 
2.3.0, or is {@code null}.
-     * 
-     * @since 2.3.21
-     */
-    public Configuration(Version incompatibleImprovements) {
-        super(incompatibleImprovements);
-        
-        // We postpone this until here (rather that doing this in static 
initializer) for two reason:
-        // - Class initialization errors are often not reported very well
-        // - This way we avoid the error if FM isn't actually used
-        checkFreeMarkerVersionClash();
-        
-        NullArgumentException.check("incompatibleImprovements", 
incompatibleImprovements);
-        this.incompatibleImprovements = incompatibleImprovements;
-        
-        createTemplateCache();
-        loadBuiltInSharedVariables();
-    }
-
-    private static void checkFreeMarkerVersionClash() {
-        if (FM_24_DETECTED) {
-            throw new RuntimeException("Clashing FreeMarker versions (" + 
VERSION + " and some post-2.3.x) detected: "
-                    + "found post-2.3.x class " + FM_24_DETECTION_CLASS_NAME + 
". You probably have two different "
-                    + "freemarker.jar-s in the classpath.");
-        }
-    }
-    
-    private void createTemplateCache() {
-        cache = new TemplateCache(
-                null,
-                getDefaultCacheStorage(),
-                getDefaultTemplateLookupStrategy(),
-                getDefaultTemplateNameFormat(),
-                null,
-                this);
-        cache.clear(); // for fully BC behavior
-        cache.setDelay(5000);
-    }
-    
-    private void recreateTemplateCacheWith(
-            TemplateLoader loader, CacheStorage storage,
-            TemplateLookupStrategy templateLookupStrategy, TemplateNameFormat 
templateNameFormat,
-            TemplateConfigurationFactory templateConfigurations) {
-        TemplateCache oldCache = cache;
-        cache = new TemplateCache(
-                loader, storage, templateLookupStrategy, templateNameFormat, 
templateConfigurations, this);
-        cache.clear(false);
-        cache.setDelay(oldCache.getDelay());
-        cache.setLocalizedLookup(localizedLookup);
-    }
-    
-    private void recreateTemplateCache() {
-        recreateTemplateCacheWith(cache.getTemplateLoader(), 
cache.getCacheStorage(),
-                cache.getTemplateLookupStrategy(), 
cache.getTemplateNameFormat(),
-                getTemplateConfigurations());
-    }
-    
-    private TemplateLookupStrategy getDefaultTemplateLookupStrategy() {
-        return getDefaultTemplateLookupStrategy(getIncompatibleImprovements());
-    }
-    
-    static TemplateLookupStrategy getDefaultTemplateLookupStrategy(Version 
incompatibleImprovements) {
-        return TemplateLookupStrategy.DEFAULT_2_3_0;
-    }
-    
-    private TemplateNameFormat getDefaultTemplateNameFormat() {
-        return getDefaultTemplateNameFormat(getIncompatibleImprovements());
-    }
-    
-    static TemplateNameFormat getDefaultTemplateNameFormat(Version 
incompatibleImprovements) {
-        return TemplateNameFormat.DEFAULT_2_3_0;
-    }
-    
-    private CacheStorage getDefaultCacheStorage() {
-        return createDefaultCacheStorage(getIncompatibleImprovements(), 
getCacheStorage()); 
-    }
-    
-    static CacheStorage createDefaultCacheStorage(Version 
incompatibleImprovements, CacheStorage existingCacheStorage) {
-        if (existingCacheStorage instanceof DefaultSoftCacheStorage) {
-            return existingCacheStorage;
-        }
-        return new DefaultSoftCacheStorage(); 
-    }
-    
-    static CacheStorage createDefaultCacheStorage(Version 
incompatibleImprovements) {
-        return createDefaultCacheStorage(incompatibleImprovements, null); 
-    }
-    
-    private static class DefaultSoftCacheStorage extends SoftCacheStorage {
-        // Nothing to override
-    }
-
-    private TemplateExceptionHandler getDefaultTemplateExceptionHandler() {
-        return 
getDefaultTemplateExceptionHandler(getIncompatibleImprovements());
-    }
-    
-    private boolean getDefaultLogTemplateExceptions() {
-        return getDefaultLogTemplateExceptions(getIncompatibleImprovements());
-    }
-    
-    private ObjectWrapper getDefaultObjectWrapper() {
-        return getDefaultObjectWrapper(getIncompatibleImprovements());
-    }
-    
-    // Package visible as Configurable needs this to initialize the field 
defaults.
-    final static TemplateExceptionHandler 
getDefaultTemplateExceptionHandler(Version incompatibleImprovements) {
-        return TemplateExceptionHandler.DEBUG_HANDLER;
-    }
-
-    // Package visible as Configurable needs this to initialize the field 
defaults.
-    final static boolean getDefaultLogTemplateExceptions(Version 
incompatibleImprovements) {
-        return true;
-    }
-    
-    @Override
-    public Object clone() {
-        try {
-            Configuration copy = (Configuration) super.clone();
-            copy.sharedVariables = new HashMap(sharedVariables);
-            copy.localeToCharsetMap = new 
ConcurrentHashMap(localeToCharsetMap);
-            copy.recreateTemplateCacheWith(
-                    cache.getTemplateLoader(), cache.getCacheStorage(),
-                    cache.getTemplateLookupStrategy(), 
cache.getTemplateNameFormat(),
-                    cache.getTemplateConfigurations());
-            return copy;
-        } catch (CloneNotSupportedException e) {
-            throw new BugException("Cloning failed", e);
-        }
-    }
-    
-    private void loadBuiltInSharedVariables() {
-        sharedVariables.put("capture_output", new CaptureOutput());
-        sharedVariables.put("compress", StandardCompress.INSTANCE);
-        sharedVariables.put("html_escape", new HtmlEscape());
-        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();
-    }
-
-    /**
-     * Returns the default (singleton) Configuration object. Note that you can
-     * create as many separate configurations as you wish; this global instance
-     * is provided for convenience, or when you have no reason to use a 
separate
-     * instance.
-     * 
-     * @deprecated The usage of the static singleton (the "default")
-     * {@link Configuration} instance can easily cause erroneous, unpredictable
-     * behavior. This is because multiple independent software components may 
use
-     * FreeMarker internally inside the same application, so they will 
interfere
-     * because of the common {@link Configuration} instance. Each such 
component
-     * should use its own private {@link Configuration} object instead, that it
-     * typically creates with <code>new Configuration()</code> when the 
component
-     * is initialized.
-     */
-    @Deprecated
-    static public Configuration getDefaultConfiguration() {
-        Configuration defaultConfig = Configuration.defaultConfig;
-        if (defaultConfig == null) {
-            synchronized (defaultConfigLock) {
-                defaultConfig = Configuration.defaultConfig;
-                if (defaultConfig == null) {
-                    defaultConfig = new Configuration();
-                    Configuration.defaultConfig = defaultConfig; 
-                }
-            }
-        }
-        return defaultConfig;
-    }
-
-    /**
-     * Sets the Configuration object that will be retrieved from future calls
-     * to {@link #getDefaultConfiguration()}.
-     * 
-     * @deprecated Using the "default" {@link Configuration} instance can
-     * easily lead to erroneous, unpredictable behaviour.
-     * See more {@link Configuration#getDefaultConfiguration() here...}.
-     */
-    @Deprecated
-    static public void setDefaultConfiguration(Configuration config) {
-        synchronized (defaultConfigLock) {
-            defaultConfig = config;
-        }
-    }
-    
-    /**
-     * Sets a {@link TemplateLoader} that is used to look up and load 
templates;
-     * as a side effect the template cache will be emptied.
-     * By providing your own {@link TemplateLoader} implementation, you can 
load templates from whatever kind of
-     * storages, like from relational databases, NoSQL-storages, etc.
-     * 
-     * <p>Convenience methods exists to install commonly used loaders, instead 
of using this method:
-     * {@link #setClassForTemplateLoading(Class, String)}, 
-     * {@link #setClassLoaderForTemplateLoading(ClassLoader, String)}, 
-     * {@link #setDirectoryForTemplateLoading(File)}, and
-     * {@link #setServletContextForTemplateLoading(Object, String)}.
-     * 
-     * <p>You can chain several {@link TemplateLoader}-s together with {@link 
MultiTemplateLoader}.
-     * 
-     * <p>Default value: You should always set the template loader instead of 
relying on the default value.
-     * (But if you still care what it is, before "incompatible improvements" 
2.3.21 it's a {@link FileTemplateLoader}
-     * that uses the current directory as its root; as it's hard tell what 
that directory will be, it's not very useful
-     * and dangerous. Starting with "incompatible improvements" 2.3.21 the 
default is {@code null}.)   
-     */
-    public void setTemplateLoader(TemplateLoader templateLoader) {
-        // "synchronized" is removed from the API as it's not safe to set 
anything after publishing the Configuration
-        synchronized (this) {
-            if (cache.getTemplateLoader() != templateLoader) {
-                recreateTemplateCacheWith(templateLoader, 
cache.getCacheStorage(),
-                        cache.getTemplateLookupStrategy(), 
cache.getTemplateNameFormat(),
-                        cache.getTemplateConfigurations());
-            }
-            templateLoaderExplicitlySet = true;
-        }
-    }
-    
-    /**
-     * Resets the setting to its default, as if it was never set. This means 
that when you change the
-     * {@code incompatibe_improvements} setting later, the default will also 
change as appropriate. Also 
-     * {@link #isTemplateLoaderExplicitlySet()} will return {@code false}.
-     * 
-     * @since 2.3.22
-     */
-    public void unsetTemplateLoader() {
-        if (templateLoaderExplicitlySet) {
-            setTemplateLoader(null);
-            templateLoaderExplicitlySet = false;
-        }
-    }
-
-    /**
-     * Tells if {@link #setTemplateLoader(TemplateLoader)} (or equivalent) was 
already called on this instance.
-     * 
-     * @since 2.3.22
-     */
-    public boolean isTemplateLoaderExplicitlySet() {
-        return templateLoaderExplicitlySet;
-    }
-
-    /**
-     * The getter pair of {@link #setTemplateLoader(TemplateLoader)}.
-     */
-    public TemplateLoader getTemplateLoader() {
-        if (cache == null) {
-            return null;
-        }
-        return cache.getTemplateLoader();
-    }
-    
-    /**
-     * Sets a {@link TemplateLookupStrategy} that is used to look up templates 
based on the requested name; as a side
-     * effect the template cache will be emptied. The default value is {@link 
TemplateLookupStrategy#DEFAULT_2_3_0}.
-     * 
-     * @since 2.3.22
-     */
-    public void setTemplateLookupStrategy(TemplateLookupStrategy 
templateLookupStrategy) {
-        if (cache.getTemplateLookupStrategy() != templateLookupStrategy) {
-            recreateTemplateCacheWith(cache.getTemplateLoader(), 
cache.getCacheStorage(),
-                    templateLookupStrategy, cache.getTemplateNameFormat(),
-                    cache.getTemplateConfigurations());
-        }
-        templateLookupStrategyExplicitlySet = true;
-    }
-
-    /**
-     * Resets the setting to its default, as if it was never set. This means 
that when you change the
-     * {@code incompatibe_improvements} setting later, the default will also 
change as appropriate. Also 
-     * {@link #isTemplateLookupStrategyExplicitlySet()} will return {@code 
false}.
-     * 
-     * @since 2.3.22
-     */
-    public void unsetTemplateLookupStrategy() {
-        if (templateLookupStrategyExplicitlySet) {
-            setTemplateLookupStrategy(getDefaultTemplateLookupStrategy());
-            templateLookupStrategyExplicitlySet = false;
-        }
-    }
-    
-    /**
-     * Tells if {@link #setTemplateLookupStrategy(TemplateLookupStrategy)} (or 
equivalent) was already called on this
-     * instance.
-     * 
-     * @since 2.3.22
-     */
-    public boolean isTemplateLookupStrategyExplicitlySet() {
-        return templateLookupStrategyExplicitlySet;
-    }
-    
-    /**
-     * The getter pair of {@link 
#setTemplateLookupStrategy(TemplateLookupStrategy)}.
-     */
-    public TemplateLookupStrategy getTemplateLookupStrategy() {
-        if (cache == null) {
-            return null;
-        }
-        return cache.getTemplateLookupStrategy();
-    }
-    
-    /**
-     * Sets the template name format used. The default is {@link 
TemplateNameFormat#DEFAULT_2_3_0}, while the
-     * recommended value for new projects is {@link 
TemplateNameFormat#DEFAULT_2_4_0}.
-     * 
-     * @since 2.3.22
-     */
-    public void setTemplateNameFormat(TemplateNameFormat templateNameFormat) {
-        if (cache.getTemplateNameFormat() != templateNameFormat) {
-            recreateTemplateCacheWith(cache.getTemplateLoader(), 
cache.getCacheStorage(),
-                    cache.getTemplateLookupStrategy(), templateNameFormat,
-                    cache.getTemplateConfigurations());
-        }
-        templateNameFormatExplicitlySet = true;
-    }
-
-    /**
-     * Resets the setting to its default, as if it was never set. This means 
that when you change the
-     * {@code incompatibe_improvements} setting later, the default will also 
change as appropriate. Also 
-     * {@link #isTemplateNameFormatExplicitlySet()} will return {@code false}.
-     * 
-     * @since 2.3.22
-     */
-    public void unsetTemplateNameFormat() {
-        if (templateNameFormatExplicitlySet) {
-            setTemplateNameFormat(getDefaultTemplateNameFormat());
-            templateNameFormatExplicitlySet = false;
-        }
-    }
-    
-    /**
-     * Tells if {@link #setTemplateNameFormat(TemplateNameFormat)} (or 
equivalent) was already called on this instance.
-     * 
-     * @since 2.3.22
-     */
-    public boolean isTemplateNameFormatExplicitlySet() {
-        return templateNameFormatExplicitlySet;
-    }
-
-    /**
-     * The getter pair of {@link #setTemplateNameFormat(TemplateNameFormat)}.
-     */
-    public TemplateNameFormat getTemplateNameFormat() {
-        if (cache == null) {
-            return null;
-        }
-        return cache.getTemplateNameFormat();
-    }
-    
-    /**
-     * Sets a {@link TemplateConfigurationFactory} that will configure 
individual templates where their settings differ
-     * from those coming from the common {@link Configuration} object. A 
typical use case for that is specifying the
-     * {@link TemplateConfiguration#setOutputFormat(OutputFormat) 
outputFormat} for templates based on their file
-     * extension or parent directory.
-     * 
-     * <p>
-     * Note that the settings suggested by standard file extensions are 
stronger than that you set here. See
-     * {@link #setRecognizeStandardFileExtensions(boolean)} for more 
information about standard file extensions.
-     * 
-     * <p>See "Template configurations" in the FreeMarker Manual for examples.
-     * 
-     * @since 2.3.24
-     */
-    public void setTemplateConfigurations(TemplateConfigurationFactory 
templateConfigurations) {
-        if (cache.getTemplateConfigurations() != templateConfigurations) {
-            if (templateConfigurations != null) {
-                templateConfigurations.setConfiguration(this);
-            }
-            recreateTemplateCacheWith(cache.getTemplateLoader(), 
cache.getCacheStorage(),
-                    cache.getTemplateLookupStrategy(), 
cache.getTemplateNameFormat(),
-                    templateConfigurations);
-        }
-    }
-    
-    /**
-     * The getter pair of {@link 
#setTemplateConfigurations(TemplateConfigurationFactory)}.
-     */
-    public TemplateConfigurationFactory getTemplateConfigurations() {
-        if (cache == null) {
-            return null;
-        }
-        return cache.getTemplateConfigurations();
-    }
-
-    /**
-     * Sets the {@link CacheStorage} used for caching {@link Template}-s;
-     * the earlier content of the template cache will be dropt.
-     * 
-     * The default is a {@link SoftCacheStorage}. If the total size of the 
{@link Template}
-     * objects is significant but most templates are used rarely, using a
-     * {@link MruCacheStorage} instead might be advisable. If you don't want 
caching at
-     * all, use {@link freemarker.cache.NullCacheStorage} (you can't use 
{@code null}).
-     * 
-     * <p>Note that setting the cache storage will re-create the template 
cache, so
-     * all its content will be lost.
-     */
-    public void setCacheStorage(CacheStorage cacheStorage) {
-        // "synchronized" is removed from the API as it's not safe to set 
anything after publishing the Configuration
-        synchronized (this) {
-            if (getCacheStorage() != cacheStorage) {
-                recreateTemplateCacheWith(cache.getTemplateLoader(), 
cacheStorage,
-                        cache.getTemplateLookupStrategy(), 
cache.getTemplateNameFormat(),
-                        cache.getTemplateConfigurations());
-            }
-            cacheStorageExplicitlySet = true;
-        }
-    }
-    
-    /**
-     * Resets the setting to its default, as if it was never set. This means 
that when you change the
-     * {@code incompatibe_improvements} setting later, the default will also 
change as appropriate. Also 
-     * {@link #isCacheStorageExplicitlySet()} will return {@code false}.
-     * 
-     * @since 2.3.22
-     */
-    public void unsetCacheStorage() {
-        if (cacheStorageExplicitlySet) {
-            setCacheStorage(getDefaultCacheStorage());
-            cacheStorageExplicitlySet = false;
-        }
-    }
-    
-    /**
-     * Tells if {@link #setCacheStorage(CacheStorage)} (or equivalent) was 
already called on this instance.
-     * 
-     * @since 2.3.22
-     */
-    public boolean isCacheStorageExplicitlySet() {
-        return cacheStorageExplicitlySet;
-    }
-    
-    /**
-     * The getter pair of {@link #setCacheStorage(CacheStorage)}.
-     * 
-     * @since 2.3.20
-     */
-    public CacheStorage getCacheStorage() {
-        // "synchronized" is removed from the API as it's not safe to set 
anything after publishing the Configuration
-        synchronized (this) {
-            if (cache == null) {
-                return null;
-            }
-            return cache.getCacheStorage();
-        }
-    }
-
-    /**
-     * Sets the file system directory from which to load templates. This is 
equivalent to
-     * {@code setTemplateLoader(new FileTemplateLoader(dir))}, so see
-     * {@link FileTemplateLoader#FileTemplateLoader(File)} for more details.
-     * 
-     * <p>
-     * Note that FreeMarker can load templates from non-file-system sources 
too. See
-     * {@link #setTemplateLoader(TemplateLoader)} from more details.
-     * 
-     * <p>
-     * Note that this shouldn't be used for loading templates that are coming 
from a WAR; use
-     * {@link #setServletContextForTemplateLoading(Object, String)} then. 
Servlet containers might not unpack the WAR
-     * file, in which case you clearly can't access the contained files via 
{@link File}. Even if the WAR is unpacked,
-     * the servlet container might not expose the location as a {@link File}.
-     * {@link #setServletContextForTemplateLoading(Object, String)} on the 
other hand will work in all these cases.
-     */
-    public void setDirectoryForTemplateLoading(File dir) throws IOException {
-        TemplateLoader tl = getTemplateLoader();
-        if (tl instanceof FileTemplateLoader) {
-            String path = ((FileTemplateLoader) tl).baseDir.getCanonicalPath();
-            if (path.equals(dir.getCanonicalPath()))
-                return;
-        }
-        setTemplateLoader(new FileTemplateLoader(dir));
-    }
-
-    /**
-     * Sets the servlet context from which to load templates.
-     * This is equivalent to {@code setTemplateLoader(new 
WebAppTemplateLoader(sctxt, path))}
-     * or {@code setTemplateLoader(new WebAppTemplateLoader(sctxt))} if {@code 
path} was
-     * {@code null}, so see {@code freemarker.cache.WebAppTemplateLoader} for 
more details.
-     * 
-     * @param servletContext the {@code javax.servlet.ServletContext} object. 
(The declared type is {@link Object}
-     *        to prevent class loading error when using FreeMarker in an 
environment where
-     *        there's no servlet classes available.)
-     * @param path the path relative to the ServletContext.
-     *
-     * @see #setTemplateLoader(TemplateLoader)
-     */
-    public void setServletContextForTemplateLoading(Object servletContext, 
String path) {
-        try {
-            // Don't introduce linking-time dependency on servlets
-            final Class webappTemplateLoaderClass = 
ClassUtil.forName("freemarker.cache.WebAppTemplateLoader");
-            
-            // Don't introduce linking-time dependency on servlets
-            final Class servletContextClass = 
ClassUtil.forName("javax.servlet.ServletContext");
-            
-            final Class[] constructorParamTypes;
-            final Object[] constructorParams;
-            if (path == null) {
-                constructorParamTypes = new Class[] { servletContextClass };
-                constructorParams = new Object[] { servletContext };
-            } else {
-                constructorParamTypes = new Class[] { servletContextClass, 
String.class };
-                constructorParams = new Object[] { servletContext, path };
-            }
-            
-            setTemplateLoader( (TemplateLoader)
-                    webappTemplateLoaderClass
-                            .getConstructor(constructorParamTypes)
-                                    .newInstance(constructorParams));
-        } catch (Exception e) {
-            throw new BugException(e);
-        }
-    }
-
-    /**
-     * Sets the class whose {@link Class#getResource(String)} method will be 
used to load templates, from the inside the
-     * package specified. See {@link 
ClassTemplateLoader#ClassTemplateLoader(Class, String)} for more details.
-     * 
-     * @param basePackagePath
-     *            Separate steps with {@code "/"}, not {@code "."}, and note 
that it matters if this starts with
-     *            {@code /} or not. See {@link 
ClassTemplateLoader#ClassTemplateLoader(Class, String)} for more details.
-     * 
-     * @see #setClassLoaderForTemplateLoading(ClassLoader, String)
-     * @see #setTemplateLoader(TemplateLoader)
-     */
-    public void setClassForTemplateLoading(Class resourceLoaderClass, String 
basePackagePath) {
-        setTemplateLoader(new ClassTemplateLoader(resourceLoaderClass, 
basePackagePath));
-    }
-    
-    /**
-     * Sets the {@link ClassLoader} whose {@link 
ClassLoader#getResource(String)} method will be used to load templates,
-     * from the inside the package specified. See {@link 
ClassTemplateLoader#ClassTemplateLoader(Class, String)} for
-     * more details.
-     * 
-     * @param basePackagePath
-     *            Separate steps with {@code "/"}, not {@code "."}. See
-     *            {@link ClassTemplateLoader#ClassTemplateLoader(Class, 
String)} for more details.
-     * 
-     * @see #setClassForTemplateLoading(Class, String)
-     * @see #setTemplateLoader(TemplateLoader)
-     * 
-     * @since 2.3.22
-     */
-    public void setClassLoaderForTemplateLoading(ClassLoader classLoader, 
String basePackagePath) {
-        setTemplateLoader(new ClassTemplateLoader(classLoader, 
basePackagePath));
-    }
-
-    /**
-     * Sets the time in seconds that must elapse before checking whether there 
is a newer version of a template "file"
-     * than the cached one.
-     * 
-     * <p>
-     * Historical note: Despite what the API documentation said earlier, this 
method is <em>not</em> thread-safe. While
-     * it works well on most hardware, it's not guaranteed that FreeMarker 
will see the update in all threads, and
-     * theoretically it's also possible that it will see a value that's a 
binary mixture of the new and the old one.
-     * 
-     * @deprecated Use {@link #setTemplateUpdateDelayMilliseconds(long)} 
instead, because the time granularity of this method
-     *             is often misunderstood to be milliseconds.
-     */
-    @Deprecated
-    public void setTemplateUpdateDelay(int seconds) {
-        cache.setDelay(1000L * seconds);
-    }
-
-    /**
-     * Sets the time in milliseconds that must elapse before checking whether 
there is a newer version of a template
-     * "file" exists than the cached one. Defaults to 5000 ms.
-     * 
-     * <p>
-     * When you get a template via {@link #getTemplate(String)} (or some of 
its overloads). FreeMarker will try to get
-     * the template from the template cache. If the template is found, and at 
least this amount of time was elapsed
-     * since the template last modification date was checked, FreeMarker will 
re-check the last modification date (this
-     * could mean I/O), possibly reloading the template and updating the cache 
as a consequence (can mean even more
-     * I/O). The {@link #getTemplate(String)} (or some of its overloads) call 
will only return after this all is
-     * done, so it will return the fresh template.
-     * 
-     * @since 2.3.23
-     */
-    public void setTemplateUpdateDelayMilliseconds(long millis) {
-        cache.setDelay(millis);
-    }
-    
-    /**
-     * The getter pair of {@link #setTemplateUpdateDelayMilliseconds(long)}.
-     * 
-     * @since 2.3.23
-     */
-    public long getTemplateUpdateDelayMilliseconds() {
-        return cache.getDelay();
-    }
-    
-    @Override
-    public void setObjectWrapper(ObjectWrapper objectWrapper) {
-        ObjectWrapper prevObjectWrapper = getObjectWrapper();
-        super.setObjectWrapper(objectWrapper);
-        objectWrapperExplicitlySet = true;
-        if (objectWrapper != prevObjectWrapper) {
-            try {
-                setSharedVariablesFromRewrappableSharedVariables();
-            } catch (TemplateModelException e) {
-                throw new RuntimeException(
-                        "Failed to re-wrap earliearly set shared variables 
with the newly set object wrapper",
-                        e);
-            }
-        }
-    }
-    
-    /**
-     * Resets the setting to its default, as if it was never set. This means 
that when you change the
-     * {@code incompatibe_improvements} setting later, the default will also 
change as appropriate. Also 
-     * {@link #isObjectWrapperExplicitlySet()} will return {@code false}.
-     * 
-     * @since 2.3.22
-     */
-    public void unsetObjectWrapper() {
-        if (objectWrapperExplicitlySet) {
-            setObjectWrapper(getDefaultObjectWrapper());
-            objectWrapperExplicitlySet = false;
-        }
-    }
-    
-    /**
-     * Tells if {@link #setObjectWrapper(ObjectWrapper)} (or equivalent) was 
already called on this instance.
-     * 
-     * @since 2.3.22
-     */
-    public boolean isObjectWrapperExplicitlySet() {
-        return objectWrapperExplicitlySet;
-    }
-    
-    @Override
-    public void setTemplateExceptionHandler(TemplateExceptionHandler 
templateExceptionHandler) {
-        super.setTemplateExceptionHandler(templateExceptionHandler);
-        templateExceptionHandlerExplicitlySet = true;
-    }
-
-    /**
-     * Resets the setting to its default, as if it was never set. This means 
that when you change the
-     * {@code incompatibe_improvements} setting later, the default will also 
change as appropriate. Also 
-     * {@link #isTemplateExceptionHandlerExplicitlySet()} will return {@code 
false}.
-     * 
-     * @since 2.3.22
-     */
-    public void unsetTemplateExceptionHandler() {
-        if (templateExceptionHandlerExplicitlySet) {
-            setTemplateExceptionHandler(getDefaultTemplateExceptionHandler());
-            templateExceptionHandlerExplicitlySet = false;
-        }
-    }
-    
-    /**
-     * Tells if {@link #setTemplateExceptionHandler(TemplateExceptionHandler)} 
(or equivalent) was already called on
-     * this instance.
-     * 
-     * @since 2.3.22
-     */
-    public boolean isTemplateExceptionHandlerExplicitlySet() {
-        return templateExceptionHandlerExplicitlySet;
-    }    
-    
-    /**
-     * @since 2.3.22
-     */
-    @Override
-    public void setLogTemplateExceptions(boolean value) {
-        super.setLogTemplateExceptions(value);
-        logTemplateExceptionsExplicitlySet = true;
-    }
-
-    /**
-     * Resets the setting to its default, as if it was never set. This means 
that when you change the
-     * {@code incompatibe_improvements} setting later, the default will also 
change as appropriate. Also 
-     * {@link #isTemplateExceptionHandlerExplicitlySet()} will return {@code 
false}.
-     * 
-     * @since 2.3.22
-     */
-    public void unsetLogTemplateExceptions() {
-        if (logTemplateExceptionsExplicitlySet) {
-            setLogTemplateExceptions(getDefaultLogTemplateExceptions());
-            logTemplateExceptionsExplicitlySet = false;
-        }
-    }
-    
-    /**
-     * Tells if {@link #setLogTemplateExceptions(boolean)} (or equivalent) was 
already called on this instance.
-     * 
-     * @since 2.3.22
-     */
-    public boolean isLogTemplateExceptionsExplicitlySet() {
-        return logTemplateExceptionsExplicitlySet;
-    }
-
-    /**
-     * Use {@link #Configuration(Version)} instead if possible; see the 
meaning of the parameter there.
-     * If the default value of a setting depends on the {@code 
incompatibleImprovements} and the value of that setting
-     * was never set in this {@link Configuration} object through the public 
API, its value will be set to the default
-     * value appropriate for the new {@code incompatibleImprovements}. (This 
adjustment of a setting value doesn't
-     * count as setting that setting, so setting {@code 
incompatibleImprovements} for multiple times also works as
-     * expected.) Note that if the {@code template_loader} have to be changed 
because of this, the template cache will
-     * be emptied.
-     * 
-     * @throws IllegalArgumentException
-     *             If {@code incompatibleImmprovements} refers to a version 
that wasn't released yet when the currently
-     *             used FreeMarker version was released, or is less than 
2.3.0, or is {@code null}.
-     * 
-     * @since 2.3.20
-     */
-    public void setIncompatibleImprovements(Version incompatibleImprovements) {
-        _TemplateAPI.checkVersionNotNullAndSupported(incompatibleImprovements);
-        
-        if (!this.incompatibleImprovements.equals(incompatibleImprovements)) {
-            this.incompatibleImprovements = incompatibleImprovements;
-            
-            if (!templateLoaderExplicitlySet) {
-                templateLoaderExplicitlySet = true; 
-                unsetTemplateLoader();
-            }
-
-            if (!templateLookupStrategyExplicitlySet) {
-                templateLookupStrategyExplicitlySet = true;
-                unsetTemplateLookupStrategy();
-            }
-            
-            if (!templateNameFormatExplicitlySet) {
-                templateNameFormatExplicitlySet = true;
-                unsetTemplateNameFormat();
-            }
-            
-            if (!cacheStorageExplicitlySet) {
-                cacheStorageExplicitlySet = true;
-                unsetCacheStorage();
-            }
-            
-            if (!templateE

<TRUNCATED>

Reply via email to