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/07/16 23:15:57 UTC

[3/4] incubator-freemarker git commit: Made the change log more organized.

Made the change log more organized.


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

Branch: refs/heads/3
Commit: 7e171b74696a17e959245104528b205f4bfbb1a0
Parents: 51e4bfe
Author: ddekany <dd...@apache.org>
Authored: Sun Jul 16 20:25:04 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Jul 16 20:25:04 2017 +0200

----------------------------------------------------------------------
 FM3-CHANGE-LOG.txt | 497 +++++++++++++++++++++++++++---------------------
 1 file changed, 281 insertions(+), 216 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7e171b74/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt
index 7cbd223..9004675 100644
--- a/FM3-CHANGE-LOG.txt
+++ b/FM3-CHANGE-LOG.txt
@@ -16,9 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
- 
+
 Because the Manual won't be updated for a good while, we will lead
-the FreeMarker 3 changelog here:
+the FreeMarker 3 changelog here.
+
+To understand the purpose of FreeMarker 3 (FM3 from now on), please see:
+https://cwiki.apache.org/confluence/display/FREEMARKER/FreeMarker+3
+
+
+Template language changes
+=========================
+
+Major changes / features
+------------------------
 
 - Switched to camel case as the only supported naming convention. This is as if in FM2 you set the "namingConvention"
   configuration setting to "camelCase", however the "namingConvention" setting was removed, as no other convention will
@@ -28,25 +38,65 @@ the FreeMarker 3 changelog here:
   then `template_loader` becomes to `templateLoader`, and if you use the XML features, then `node.@@nested_markup`
   becomes to `node.@@nestedMarkup`.
   Note that the template converter tool takes care of this conversion.
-- Increased version number to 3.0.0 (nightly aka. SNAPSHOT)
-- Removed legacy extensions: rhyno, jython, xml (not to be confused with dom), jdom, ant.
-- Servlet 3.0 and JSP 2.2 and is the minimum requirement now (if Serlvet/JSP features are used at all).
-- Removed freemarker.ext.log, our log abstraction layer from the old times when there was no clear winner on this field.
-  Added org.slf4j:slf4j-api as required dependency instead.
-- Log categories are now simply the full qualified class name of the logging classes. There are no predefined log
-  categories (such as "freemarker.runtime", etc.) anymore. This is to follow the common practices in logging.
-- Removed all classes with "main" methods that were part of freemarker.jar. Such tools should be separate artifacts,
-  not part of the library, and they are often classified as CWE-489 "Leftover Debug Code". The removed classes are:
-  freemarker.core.CommandLine, freemarker.ext.dom.Transform, freemarker.template.utility.ToCanonical
-- Removed classic_compatible (classicCompatible) setting, which was used to emulate some of the FreeMarker 1.x behavior
-- Removed utility TemplateModel-s that can very easily mean a security problem: freemarker.template.utility.Execute and 
-  freemarker.template.utility.ObjectConstructor
-- Removed TemplateClassResolver.SAFER_RESOLVER, because the classes it has blocked were removed from FreeMarker, so it's
-  the same as UNRESTRICTED_RESOLVER
-- Removed the strict_syntax setting, and so also the support for FTL tags without #. This was a FreeMarker 1.x
-  compatibility option.
-- Removed deprecated FMParser contstructors.
-- Minimum Java version increased to 7, but without try-with-resource as that's unavailable before Android 4.4 KitKat.
+
+Smaller changes
+---------------
+
+Node: Changes already mentioned above aren't repeated here!
+
+- Renamed `?datetime` and `?datetimeIfUnknown` and the `datetimeFormat` setting to
+  `?dateTime` and `?dateTimeIfUnknown` and `dateTimeFormat`.
+- Removed support for all old glitches that you could turn on/off with incompatibleImprovements in FM2
+- Removed some long deprecated template language directives:
+  - <#call ...> (deprecated by <@... />)
+  - <#comment>...</#comment> (deprecated by <#-- ... -->)
+  - <#transform ...>...</#transform> (deprecated by <@....@...>)
+  - <#foreach x in xs>...</#foreach> (deprecated by <#list xs as x>...</#list>)
+- #include has no "encoding" parameter anymore (see reasons in the API changes)
+- Removed long deprecated `#{}` interpolations. They are treated as plain static text now. (The
+  template converter tool translates these to `${}` interpolations. For example `#{x}` is simply
+  translated to `${b}`, while `#{x; m1M3}` is translated to `${x?string('0.0##')}`).
+- You can't close #attempt/#recover with `</#recover>` anymore, only with `<#attempt>`. This was the
+  standard form in FM2 as well, and is consistent with how #if/#else works. (The template converter
+  tool does this conversion.)
+- Inside a #switch, #case can't be after #default anymore (this is actually a bug in FM2)
+  (The template converter can't fix this automatically, but reports it as an error.)
+- #else and #elseIf tags must be ended without "/", for example, <#else/> is illegal now, <#else> is legal.
+  (The template converter tool does this conversion.)
+- .template_name now means the same as .current_template_name (it doesn't emulate 2.3 glitches anymore)
+
+
+Java API changes
+================
+
+Major changes / features
+------------------------
+
+- Modularized the project. Now we have these published jar-s:
+  - org.apache.freemarker:freemarker-core
+  - org.apache.freemarker:freemarker-servlet
+  - org.apache.freemarker:freemarker-dom
+  - org.apache.freemarker:freemarker-spring
+  There are several other internal modules related to testing and such; these aren't published.
+- Reorganized package structure: Everything starts with org.apache.freemarker, and continues with
+  subpackage that corresponds to the module (see modularization above). So we have
+  org.apache.freemarker.core (has nothing to do with the old freemarker.core), org.apache.freemarker.servlet (this
+  replaced freemarker.ext.servlet and freemarker.ext.jsp), org.apache.freemarker.dom (replaces freemarker.ext.dom), etc.
+  Directly inside org.apache.freemarker.core we have most of the classes that were in freemarker.template and
+  freemarker.core, however, model related classes (and object wrappers) were moved out to
+  org.apache.freemarker.core.model, and template loading and caching related classes to
+  org.apache.freemarker.core.templateresolver (we have a class called TemplateResolver; see later).
+  OutputFormat related classes were moved to org.apache.freemarker.core.outputformat.
+  ValueFormat related classes were moved to org.apache.freemarker.core.valueformat.
+  ArithmeticEngine related classes were moved to org.apache.freemarker.core.arithmetic.
+- Added the org.apache.freemarker.core.templateresolver.TemplateResolver class and the `templateResolver` Configuration
+  setting. This allows replacing the whole template lookup, loading and caching logic with a custom implementation,
+  giving total control over this aspect of FreeMarker, in case replacing Configuration settings like `templateLoader`
+  or `templateCacheStorage` wasn't enough. The `TemplateResolver` implementation declares which of the template resolution
+  related Configuration settings it supports (for example, it may still want to rely on the `templateLoader`, but
+  doesn't use the other settings). It's an error to set a template resolution related settings that the TemplateResolver
+  doesn't support. The default implementation, `DefaultTemplateResolver`, supports all of them of course. Note that the
+  `TemplateCache` class was removed, and was basically replaced by `DefaultTemplateResolver`.
 - Totally redesigned TemplateLoader interface. The FM2 TemplateLoader can't be adapted (wrapped) to it, but usually
   it's fairly trivial to "rearrange" an old custom TemplateLoader for the new interface. The new TemplateLoader comes
   with several advantages, such as:
@@ -67,76 +117,150 @@ the FreeMarker 3 changelog here:
     template, in case the backing storage stores such extra information. This mechanism can be used together with
     the TemplateConfiguration mechanism (already familiar from FreeMarker 2), and overrides the individual settings
     coming from there.
-- Template constructors won't close the Reader passed in as agrument anymore (because a Reader should be closed
-  by who has created it). This avoids some surprises from the past, such as the unablility to reset a Reader to a mark
-  after parsing. If you call those constructors, be sure that you close the Reader yourself. (Obviously, it doesn't
-  mater for StringReader-s.)
-- Renamed top level java package from freemarker to org.apache.freemarker 
-- Reorganized package structure. We will have a freemarker-core and a freemarker-servlet module later, so
-  we got org.apache.freemarker.core (has nothing to do with the old freemarker.core) and
-  org.apache.freemarker.servlet (this replaced freemarker.ext.servlet and freemarker.ext.jsp).
-  Directly inside org.apache.freemarker.core we have most of the classes that were in
-  freemarker.template and freemarker.core, however, model related classes (and object wrappers)
-  were moved to org.apache.freemarker.core.model, and template loading and caching related classes
-  to org.apache.freemarker.core.templateresolver (because later we will have a class called
-  TemplateResolver, which is the central class of loading and caching and template name rules).
-  OutputFormat realted classes were moved to org.apache.freemarker.core.outputformat.
-  ValueFormat related classes were moved to org.apache.freemarker.core.valueformat.
-  ArithmeticEngine related classes were moved to org.apache.freemarker.core.arithmetic.
-  freemarker.ext.dom was moved into org.apache.freemarker.dom.
-- Moved the all the static final ObjectWrapper-s to the new _StaticObjectWrappers class, and made them
-  write protected (non-configurable). Also now they come from the pool that ObjectWrapper builders use.
-- WrappingTemplateModel.objectWrapper is now final, and its statically stored default value can't be set anymore.
-- Removed SimpleObjectWrapper deprecated paramerless constructor
-- Removed ResourceBundleLocalizedString and LocalizedString: Hardly anybody has discovered these, and they had no
-  JUnit coverage.
-- The `cacheStorage` Configiration setting was renamed to `templateCacheStorage`.
-- Added the org.apache.freemarker.core.templateresolver.TemplateResolver class and the `templateResolver` Configuration
-  setting. This allows replacing the whole template lookup, loading and caching logic with a custom implementation,
-  giving total control over this aspect of FreeMarker, in case replacing Configuration settings like `templateLoader`
-  or `templateCacheStorage` wasn't enough. The `TemplateResolver` implementation declares which of the template resolution
-  related Configuration settings it supports (for example, it may still want to rely on the `templateLoader`, but
-  doesn't use the other settings). It's an error to set a template resolution related settings that the TemplateResolver
-  doesn't support. The default implementation, `DefaultTemplateResolver`, supports all of them of course. Note that the
-  `TemplateCache` class was removed, and was basically replaced by `DefaultTemplateResolver`.
-- Marked most static utility classes as internal, and renamed them to start with "_" (for example StringUtils was
-  renamed to _StringUtil, thus people won't accidentally use it when they wanted to autocomplete to Apache Commons
-  StringUtil). Created published static utility class, o.a.f.core.util.FTLUtil, which contains some methods moved
-  over from the now internal utility classes.
-- Deleted o.a.f.core.util.DOMNodeModel (it has noting to do with the standard XML support, o.a.f.core.model.dom)
-- All CacheStorage-s must be thread safe from now on (removed ConcurrentCacheStorage marker interface)
-- Removed support for incompatibleImprovements before 3.0.0. So currently 3.0.0 is the only support value.
+- Configuration is now immutable. You should use Configuration.Builder to set up the setting values, then create
+  the Configuration with the builder's build() method.
+- Configuration defaults were changed to follow the current best practices (like default charset is UTF-8 everywhere)
+- Removed freemarker.ext.log, our log abstraction layer from the old times when there was no clear winner on this field.
+  Added org.slf4j:slf4j-api as required dependency instead.
+- Added Spring support to the FreeMarker project (freemarker-spring module), instead of relying Spring developers
+  [Note: This is in very early stage, as of 2017-07-06.]
+
+
+Smaller changes (categorized)
+-----------------------------
+
+Node: Changes already mentioned above aren't repeated here!
+
+Core / Configuration
+....................
+
+- Configuration is now immutable (see earlier), so `Configuration.Builder` was added, which extends
+  `Configuration.ExtendableBuilder`. It's now possible to change the `Configuration` setting defaults by using a custom
+  subclass instead of `Configuration.Builder`. (`FreeMarkerServlet` has switched to this approach, using its own
+  builder subclass to provide defaults that makes the sense in that particular application.)
+- setClassForTemplateLoader, setDirectoryForTemplateLoading and the like were removed, instead there's just
+  setTemplateLoader. So for example. instead of  setClassForTemplateLoader(Foo.class, "templates") now you have
+  to write setTemplateLoader(new ClassTemplateLoader(Foo.class, "templates")). While it's a bit longer, it shows
+  more clearly what's happening, and always supports all TemplateLoader constructor overloads.
+- setSetting (and the like) doesn't throw ParseException (the same exception used when parsing templates) anymore,
+  but ConfigurationException. Also, on the places where ParseException was used for other than template parsing,
+  o.a.f.core.util.GenericParseException is used now instead, which doesn't have the template parsing related fields
+  that we can't fill.
 - Removed `String Configurable.getSetting(String)` and `Properties getSettings()`. It has never worked well,
   and is impossible to implement properly.
+- Added ProcessingConfiguration interface for the read-only access of template processing settings. This is similar to
+  the FM2 ParserConfiguration interface.
+- Renamed Configurable to MutableProcessingAndParserConfiguration. Made it abstract too.
+- Made Template immutable (via public API-s). Template-specific settings now can only come from the
+  TemplateConfiguration associated to the template, or from the #ftl header for some settings (most notably for
+  custom attributes).
+- Renamed ParserConfiguration to ParsingConfiguration, so that the name is more consistent with the new
+  ProcessingConfiguration.
+- Changed the defaults of some Configuration settings:
+  - Changed the default of sourceEncoding ("encoding" earlier) to UTF-8 from the platform default charset.
+    Using the platform default charset was proven to be fragile in practice,
+    like applications could break when moved to another server if the application
+    was unwillingly relying on the default.
+  - Changed the default of templateExceptionHandler (template_exception_hander) to
+    TemplateExceptionHandler.RETHROW from DEBUG
+  - Changed the default of sqlDateAndTimeTimeZone (sqlDateAndTimeTimeZone) to
+    TimeZone.default() from null (where null meant falling back to the timeZone setting value)
+  - Changed the default of templateNameFormat (templateNameFormat) to what's equivalent to
+    FM2 DefaultTemplateNameFormat24. The old DefaultTemplateNameFormat was removed, and
+    DefaultTemplateNameFormat24 was renamed to DefaultTemplateNameFormat.
+- Removed the logTemplateExceptions (log_template_exceptions) setting. FreeMarker now behaves as if it was false.
+  When a FreeMarker method throws an exception, the caller is responsible for either logging it or letting it bubble up.
+- Removed the strict_syntax setting, and so also the support for FTL tags without #. This was a FreeMarker 1.x
+  compatibility option.
+- Renamed the `cacheStorage` Configuration setting to `templateCacheStorage`.
+- Renamed the `localizedLookup` Configuration setting to `localizedTemplateLookup`.
+- Renamed the `datetimeFormat` Configuration setting to `dateTimeFormat` (following Java 8 convention).
+- Renamed the String key for the historically incorrect `autoInclude` Configuration setting to `autoIncludes`.
+- Renamed the String key for the historically incorrect `autoImport` Configuration setting to `autoImports`.
+- TemplateClassResolver.UNRESTRICTED_RESOLVER and ALLOWS_NOTHING_RESOLVER was renamed
+  to UNRESTRICTED and ALLOW_NOTHING. Also the String setting name "allows_nothing" and
+  "allowsNothing" were renamed to "allowNothing".
+- TemplateExceptionHandler.IGNORE_HANDLER, RETHROW_HANDLER, DEBUG_HANDLER and
+  HTLM_DEBUG_HANDLER was renamed to IGNORE, RETHROW, DEBUG and HTML_DEBUG
+- AttemptExceptionReporter.LOG_ERROR_REPORTER and LOG_WARN_REPORTER was renamed to
+  LOG_ERROR and LOG_WARN (to be consistent with the new TemplateExceptionHandler names)
+- Removed TemplateClassResolver.SAFER_RESOLVER, because the classes it has blocked were removed from FreeMarker, so it's
+  the same as UNRESTRICTED_RESOLVER
+- When specifying the templateUpdateDelay configuration setting with a String (with Properties), the time unit is
+  required, unless the value is 0.
 - Even for setting values that are class names without following `()` or other argument list, the INSTANCE field and
   the builder class will be searched now, and used instead of the constructor of the class. Earlier they weren't for
   backward compatibility.
-- Removed several deprecated methods and constants. Some notes:
-  - strict_bean_models configuration setting was removed, as it should be set on the BeansWrapper itself
-  - .template_name now means the same as .current_template_name (it doesn't emulate 2.3 glitches anymore)
-  - Removed the deprecated BeansWrapper.nullModel setting. So null is always wrapped to null now.
-  - Removed the overridable BeansWrapper.finetuneMethodAppearance method, which was deprecated by the
-    finetuneMethodAppearance setting (BeansWrapper.setFinetuneMethodAppearance).
-  - Removed NodeModel static utility classes dealing with parsing XML to DOM. How it's best to do that is environment
-    and application dependent, and it has security implications. Since XML loading/parsing is not the topic of the
-    project, these were removed. Static methods that simplify an already loaded DOM have remained, because that's
-    FreeMarker-specific functionality.
-  - Removed parameterless DefaultObjectWrapper and BeansWrapper constructors. Now specifying the
-    incomplatibleImprovement version is required.
-  - Removed the static default Configuration instance. (It's not possible to create a template with null Configuration
-    constructor argument anymore.)
-  - When specifying the templateUpdateDelay configuration setting with a String (with Properties), the time unit is
-    required, unless the value is 0.
-- setSetting (and the like) doesn't throw ParseException (the same exception used when parsing templates) anymore,
-  but ConfigurationException. Also, on the places where ParseException was used for other than template parsing,
-  o.a.f.core.util.GenericParseException is used now instead, which doesn't have the template parsing related fields
-  that we can't fill.
-- Removed DefaultObjectWrapper settings that only exist so that you can set backward compatible behavior instead of
-  the recommended value: useAdaptersForContainers, forceLegacyNonListCollections, iterableSupport, simpleMapWrapper
+- Removed the static default Configuration instance. (It's not possible to create a template with null Configuration
+  constructor argument anymore.)
+- The strict_bean_models configuration setting was removed, as it should be set on the BeansWrapper itself
+- When looking for a builder class in builder expressions used in setting values like `com.example.Foo()`, now we first
+  look for com.example.Foo.Builder, and only then com.example.FooBuilder.
+- Removed Configuration.Builder.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.
+- As "attributes" can't be modifiable now that Configuration is immutable, and hence didn't fit into the new system,
+  the "attributes" setting was removed. In place of that, two new concepts were introduced, targeting two different
+  "attributes" use-cases:
+    - Custom states: CustomStateKey class and the CustomStateScope interface was introduced, which
+      is somewhat similar to the now removed CustomAttribute. CustomStateScope contains one method, Object
+      `getCustomState(CustomStateKey)``, which may calls `CustomStateKey.create()` to lazily create the state object
+      for the key. `Configuration`, `Template` and `Environment` implements `CustomStateScope`, so you can store state
+      in any of these scopes.
+    - Custom settings: These have the same mutability rules as normal settings, that is, you can't modify them except in
+      builder objects and in the `Environment`. You can get their values with `getCustomSetting(Serializble key[, Object
+      defaultValue])`. If no default is specified, and the custom setting is not set, a `CustomSettingNotSetException`
+      is thrown. Just like standard settings, custom settings automatically inherited from higher scopes.
+    - In the `#ftl` header the `attributes` parameter name was changed to `customSettings`
+      (The template converter tool takes care of this conversion.)
+- Renamed Configuration.defaultEncoding to sourceEncoding, also added sourceEncoding to ParserConfiguration, and renamed
+  TemplateConfiguration.encoding and Template.encoding to sourceEncoding. (Before this, defaultEncoding was exclusive
+  to Configuration, but now it's like any other ParserConfiguration setting that can be overridden on the 3 levels.)
+- Settings that have contained a charset name (sourceEncoding, outputEncoding, URLEscapingCharset) are now of type Charset,
+  not String. For string based configuration sources (such as .properties files) this means that:
+  - Unrecognized charset names are now errors
+  - For recognized names the charset name will be normalized (like "latin1" becomes to "ISO-8859-1").
+  - In "object builder expressions" Charset values can now be constructed like `Charset("ISO-8859-5")`.
+    Note that as the type of the settings have changed, now you can't just write something like
+    `TemplateConfiguration(sourceEncoding = "UTF-8")`, but `TemplateConfiguration(sourceEncoding = Charset("UTF-8"))`.
+- Configuration-related int constants were replaced with enums:
+  - FM2 Configuration.${c}_TAG_SYNTAX with TagSyntax.${c}
+  - FM2 Configuration.${c}_AUTO_ESCAPING_POLICY with AutoEscapingPolicy.${c}
+- Removed hasCustomFormats() from configuration related API-s (we don't need it anymore)
+
+Core / Models and Object wrapping
+.................................
+
+- DefaultObjectWrapper is now immutable (has no setter methods), so most of the mutator methods (like setters) were
+  moved rom Configuration to Configuration.Builder.
+- `DefaultObjectWrapper` now has a configuration setting, `extensions`, to add `DefaultObjectWrapperExtension`-s, which
+  meant to be used for wrapping application-specific objects specially. Along with this, `DefaultObjectWrapper` now has
+  two protected methods to customze the wrapping logic, `wrapSpecialObject(Object)` and `wrapGenericObject(Object)`; the
+  last replaces the `handleUnknownType(Object)` method from FM2. `DefaultObjectWrapperExtension`-s are applied before or
+  after `wrapSpecialObject`, depending on what `DefaultObjectWrapperExtension.getPhase()` returns. See the JavaDoc of
+  `DefaultObjectWrapper.wrap(Object)` for more on wrapping phases.
+- `DefaultObjectWrapper` doesn't wrap W3C DOM nodes (XML) specially anymore, as DOM wrapping was factored out to a
+  separate jar (freemarker-dom) as part of modularizing FreeMarker. To ensure that DOM nodes are wrapped specially as
+  in FM2, the `extensions` setting of the `DefaultObjectWrapper` has to be so that it contains
+  `DOMDefaultObjectWrapperExtension.INSTANCE`. For example:
+      cfgBuilder.objectWrapper(
+              new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+                      .extensions(DOMDefaultObjectWrapperExtension.INSTANCE)
+                      .build())
+- Moved the all the static final ObjectWrapper-s to the new _StaticObjectWrappers class, and made them
+  write protected (non-configurable). Also now they come from the pool that ObjectWrapper builders use.
+- WrappingTemplateModel.objectWrapper is now final, and its statically stored default value can't be set anymore.
+- Removed SimpleObjectWrapper deprecated parameterless constructor
+- Removed the deprecated BeansWrapper.nullModel setting. So null is always wrapped to null now.
+- Removed the overridable BeansWrapper.finetuneMethodAppearance method, which was deprecated by the
+  finetuneMethodAppearance setting (BeansWrapper.setFinetuneMethodAppearance).
 - Removed BeansWrapper, which was the superclass of DefaultObjectWrapper, but wasn't recommended to be used as is.
   Removed many BeansWrapper-related classes that DefaultObjectWrapper doesn't use. This includes ModelCache and
   related classes, because DefaultObjectWrapper has only used the cache for "generic" classes (because that's where it
   has fallen back to BeansWrapper.wrap), which is inconsistent and doesn't worth the caching overhead and complexity.
+- Removed parameterless DefaultObjectWrapper and BeansWrapper constructors. Now specifying the
+  incomplatibleImprovement version is required.
+- Removed DefaultObjectWrapper settings that only exist so that you can set backward compatible behavior instead of
+  the recommended value: useAdaptersForContainers, forceLegacyNonListCollections, iterableSupport, simpleMapWrapper
 - Java methods (when using DefaultObjectWrapper) won't be accessible as sequences anyore. That is, earlier, instead of
   obj.m(1), you could write obj.m[1]. This strange feature has led to some tricky cases, while almost nobody has
   utilized it.
@@ -155,11 +279,6 @@ the FreeMarker 3 changelog here:
     of FreemarerServlet.createDefaultObjectWrapper() has changed to ObjectWrapperAndUnwrapper.) The unwrapping functionality is
     required when calling JSP custom tags/functions, and in FreeMarker 2 this was worked around with using the
     global static default DefaultObjectWrapper when the ObjectWrapper wasn't an ObjectWrapperAndUnwrapper.
-- Removed some long deprecated template language directives:
-  - <#call ...> (deprecated by <@... />)
-  - <#comment>...</#comment> (deprecated by <#-- ... -->)
-  - <#transform ...>...</#transform> (deprecated by <@....@...>)
-  - <#foreach x in xs>...</#foreach> (deprecated by <#list xs as x>...</#list>)
 - If for an indexed JavaBean property there's both an indexed read method (like `Foo getFoo(int index)`) and a normal read method
   (like Foo[] getFoo()), we prefer the normal read method, and so the result will be a clean FTL sequence (not a multi-type value
   with sequence+method type). If there's only an indexed read method, then we don't expose the property anymore, but the indexed
@@ -167,153 +286,99 @@ the FreeMarker 3 changelog here:
   indexed read method we can't create a proper sequence (which the value of the property should be), since sequences are required
   to support returning their size. (In FreeMarker 2 such sequences has thrown exception on calling size(), which caused more
   problems and confusion than it solved.)
-- When looking for a builder class in builder expressions used in setting values like `com.example.Foo()`, now we first
-  look for com.example.Foo.Builder, and only then com.example.FooBuilder.
 - 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 now immutable (has no setter methods), and can only be constructed with DefaultObjectWrapper.Builder
+
+Core / Template loading and caching
+...................................
+
+- Template constructors won't close the Reader passed in as argument anymore (because a Reader should be closed
+  by who has created it). This avoids some surprises from the past, such as the unablility to reset a Reader to a mark
+  after parsing. If you call those constructors, be sure that you close the Reader yourself. (Obviously, it doesn't
+  mater for StringReader-s.)
+- All CacheStorage-s must be thread safe from now on (removed ConcurrentCacheStorage marker interface)
 - 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, "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.sourceEncoding and Configuration.templateConfigurations (for example
-  based on the directory it is in), or with 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.
+- Configuration.getTemplate has no "encoding" parameter anymore. (Similarly #include has no "encoding" parameter
+  either). The charset of templates can be specified via Configuration.sourceEncoding and Configuration
+  .templateConfigurations (for example based on the directory it is in), or with the #ftl directive inside the
+  template. Thus, a given template always has the same charset, no mater how it's accessed.
 - Require customLookupCondition-s to be Serializable.
-- Various refactorings of Configurable and its subclasses. This is part of the preparation for making such classes immutable, and offer
-  builders to create them.
-  - Removed CustomAttribute class. Custom attribute keys can be anything Serializable.
-  - As "attributes" can't be modifiable after Builder.build(), and hence didn't fit into the new system, the "attributes" setting was removed.
-    In place of that, two new concepts were introduced, targetting two different "attributes" use-cases:
-    - Custom states: CustomStateKey class and the CustomStateScope interface was introduced, which
-      is somewhat similar to the now removed CustomAttribute. CustomStateScope contains one method, Object getCustomState(CustomStateKey), which
-      may calls CustomStateKey.create() to lazily create the state object for the key. Configuration, Template and Environment implements
-      CustomStateScope, so you can store state in any of these scopes.
-    - Custom settings: These have the same mutability rules as normal settings, that is, you can't modify them except in builders objects and
-      in the Envronment. You can get their values with `getCustomSetting(Serializble key[, Object defaultValue])`. If no default is specified,
-      and the custom setting is not set, a CustomSettingNotSetException is thrown. Just like standard settings, custom settings automatically
-      inherited from higher scopes.
-    - In the #ftl header, the `attributes` parameter name was changed to `customSettings`
-      (The template converter tool takes care of this conversion.)
-  - Added ProcessingConfiguration interface for the read-only access of template processing settings. This is similar to the
-    already existing (in FM2) ParserConfiguration interface.
-  - Renamed Configurable to MutableProcessingAndParserConfiguration. Made it abstract too.
-  - Renamed Configuration.defaultEncoding to sourceEncoding, also added sourceEncoding to ParserConfiguration, and renamed
-    TemplateConfiguration.encoding and Template.encoding to sourceEncoding. (Before this, defaultEncoding was exclusive
-    to Configuration, but now it's like any other ParserConfiguration setting that can be overidden on the 3 levels.)
-  - Made TemplateConfiguration immutable, added a TemplateConfiguration.Builder.
-  - Made Template immutable (via public API-s). Template-specific settings now can only come from the TemplateConfiguration associated
-    to the template, or from the #ftl header for some settings (most notably for custom attributes).
-  - Renamed ParserConfiguration to ParsingConfiguration, so that the name is more consistent with the new ProcessingConfiguration.
-- Settings that have contained a charset name (sourceEncoding, outputEncoding, URLEscapingCharset) are now of type Charset,
-  not String. For string based configuration sources (such as .properties files) this means that:
-  - Unrecognized charset names are now errors
-  - For recognized names the charset name will be normalized (like "latin1" becomes to "ISO-8859-1").
-  - In "object builder expressions" Charset values can now be constructed like `Charset("ISO-8859-5")`.
-    Note that as the type of the settings have changed, now you can't just write something like
-    `TemplateConfiguration(sourceEncoding = "UTF-8")`, but `TemplateConfiguration(sourceEncoding = Charset("UTF-8"))`.
-- Removed Template.templateLanguageVersion, as we solely rely on incompatibleImprovements instead.
+
+DOM (XML)
+.........
+
+- Removed NodeModel static utility classes dealing with parsing XML to DOM. How it's best to do that is environment
+  and application dependent, and it has security implications. Since XML loading/parsing is not the topic of the
+  project, these were removed. Static methods that simplify an already loaded DOM have remained, because that's
+  FreeMarker-specific functionality.
+
+Servlet
+.......
+
+- `FreeMarkerServlet` now use a `Configuration.ExtendableBuilder` to provide configuration defaults that makes for it.
+  Its API-s which were used for customizing `FreeMarkerServlet` has bean changed accordingly.
+
+Spring
+.......
+
+This is about the Spring Framework Support (freemarker-spring): FREEMARKER-54, FREEMARKER-55
+
+- ConfigurationFactoryBean, a new Spring Framework's FactoryBean to create Configuration, using Builder.
+- SpringResourceTemplateLoader, a new TemplateLoader to load templates from Spring Framework's Resources.
+- New FreeMarkerView and FreeMarkerViewResolver for MVC support. FreeMarkerView supports TaglibFactory and other
+models by default like FreemarkerServlet does.
+
+Core / Miscellaneous
+....................
+
+- Minimum Java version increased to 7, but without try-with-resource as that's unavailable before Android 4.4 KitKat.
+- Removed support for incompatibleImprovements before 3.0.0. So currently 3.0.0 is the only support value.
+- Removed legacy extensions (so these has no module): rhyno, jython, xml (not to be confused with dom), jdom, ant.
+- Servlet 3.0 and JSP 2.2 and is the minimum requirement now (if Serlvet/JSP features are used at all).
+- Log categories are now simply the full qualified class name of the logging classes. There are no predefined log
+  categories (such as "freemarker.runtime", etc.) anymore. This is to follow the common practices in logging.
+- #include-d/#import-ed templates don't inherit the charset (encoding) of the #include-ing/#import-ing template.
+  (Because, the charset of a template file is now independent of how you access it; see in template loading changes.)
+- #attempt doesn't create an additional debug level log entry when an exception is catched. It only
+  log an error level log (by default at least; see the `attemptExceptionReporter` setting)
+- Marked most static utility classes as internal, and renamed them to start with "_" (for example StringUtils was
+  renamed to _StringUtil, thus people won't accidentally use it when they wanted to autocomplete to Apache Commons
+  StringUtil). Created published static utility class, o.a.f.core.util.FTLUtil, which contains some methods moved
+  over from the now internal utility classes.
 - Template.sourceEncoding was renamed to Template.actualSourceEncoding, to emphasize that it's not the template-layer
   equivalent of the sourceEncoding ParserConfiguration setting. This is in line with Template.actualTagSyntax and the
   other "actual" properties. (Just as in FM2, Template.getParserConfiguration() still can be used get the
   sourceEncoding used during parsing.)
-- Made TemplateModel classes used by the parser for literals Serializable. (Without this attribute values set in the #ftl
-  header wouldn't be always Serializable, which in turn will sabotage making Template-s Serializable in the future.)
-- Removed hasCustomFormats() from configuration related API-s (we don't need it anymore)
 - Template.name (getName()) was renamed to Template.lookupName (getLookupName()), and Template.sourceName (Template.getSourceName())
   doesn't fall back to the lookup name anymore when it's null (however, Template.getSourceOrLookupName() was added for that). There's
   no Template.name anymore, because since sourceName was introduced, and hence the concept of template name was split into the
-  lookup and the source name, its meaning wasn't clean (but it meant the lookup name). TemplateException and ParseException 
+  lookup and the source name, its meaning wasn't clean (but it meant the lookup name). TemplateException and ParseException
   now also have the same properites: getTemplateSourceName(), getTemplateLookupName(), and even getSourceOrLookupName().
   Location information in error messages show getTemplateSourceOrLookupName().
-- Configuration.setSharedVaribles (not the typo in it) was renamed to setSharedVariables
-- Configuration is now immutable. Instead, you should use Configuration.Builder to set up the setting values, then create
-  the Configuration with the builder's build() method. Further notes:
-  - Most of the mutator methods (like setters) were moved from Configuration to Configuration.Builder. However,
-    setClassForTemplateLoader, setDirectoryForTemplateLoading and the like were removed, instead there's just
-    setTemplateLoader. So for example. instead of  setClassForTemplateLoader(Foo.class, "templates") now you have
-    to write setTemplateLoader(new ClassTemplateLoader(Foo.class, "templates")). While it's a bit longer, it shows
-    more clearly what's happening, and always supports all TemplateLoader constructor overloads.
-  - It's now possible to change the Configuration setting defaults by using a custom Configuration.ExtendableBuilder
-    subclass instead of Configuration.Builder (which is also an ExtendableBuilder subclass). FreemarkerServlet has
-    switched to this approach, using its own builder subclass to provide defaults that makes the sense in that particular
-    application. Its API-s which were used for customizing FreemarkerServlet has bean changed accordingly.
-- Modularized the project. Now we have these published jar-s:
-  - org.apache.freemarker:freemarker-core
-  - org.apache.freemarker:freemarker-servlet
-  - org.apache.freemarker:freemarker-dom
-  There are several other internal modules related to testing; these aren't published.
-- Migrated buiding from Ant to Gradle. [TODO: This is only partially done; jar building, testing and javadoc works.]
-- `DefaultObjectWrapper` now has a configuration setting, `extensions`, to add `DefaultObjectWrapperExtension`-s, which
-  meant to be used for wrapping application-specific objects specially. Along with this, `DefaultObjectWrapper` now has
-  two protected methods to customze the wrapping logic, `wrapSpecialObject(Object)` and `wrapGenericObject(Object)`; the
-  last replaces the `handleUnknownType(Object)` method from FM2. `DefaultObjectWrapperExtension`-s are applied before or
-  after `wrapSpecialObject`, depending on what `DefaultObjectWrapperExtension.getPhase()` returns. See the JavaDoc of
-  `DefaultObjectWrapper.wrap(Object)` for more on wrapping phases.
-- `DefaultObjectWrapper` doesn't wrap W3C DOM nodes (XML) specially anymore, as DOM wrapping was factored out to a
-  separate jar (freemarker-dom) as part of modularizing FreeMarker. To ensure that DOM nodes are wrapped specially as
-  in FM2, the `extensions` setting of the `DefaultObjectWrapper` has to be so that it contains
-  `DOMDefaultObjectWrapperExtension.INSTANCE`. For example:
-  
-    cfgBuilder.objectWrapper(
-            new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
-                    .extensions(DOMDefaultObjectWrapperExtension.INSTANCE)
-                    .build())
-
-- Configuration-related int constants were replaced with enums:
-  - FM2 Configuration.${c}_TAG_SYNTAX with TagSyntax.${c}
-  - FM2 Configuration.${c}_AUTO_ESCAPING_POLICY with AutoEscapingPolicy.${c}
-- TemplateClassResolver.UNRESTRICTED_RESOLVER and ALLOWS_NOTHING_RESOLVER was renamed
-  to UNRESTRICTED and ALLOW_NOTHING. Also the String setting name "allows_nothing" and
-  "allowsNothing" were renamed to "allowNothing".
-- TemplateExceptionHandler.IGNORE_HANDLER, RETHROW_HANDLER, DEBUG_HANDLER and
-  HTLM_DEBUG_HANDLER was renamed to IGNORE, RETHROW, DEBUG and HTML_DEBUG  
-- AttemptExceptionReporter.LOG_ERROR_REPORTER and LOG_WARN_REPORTER was renamed to
-  LOG_ERROR and LOG_WARN (to be consistent with the new TemplateExceptionHandler names)
-- Renamed the `cacheStorage` Configuration setting to `templateCacheStorage`.
-- Renamed the `localizedLookup` Configuration setting to `localizedLookup`.
-- Renamed the `datetimeFormat` Configuration setting to `dateTimeFormat` (following Java 8 convention).
-- Renamed the String key for the historically incorrect `autoInclude` Configuration setting to `autoIncludes`.
-- Renamed the String key for the historically incorrect `autoImport` Configuration setting to `autoImports`.
-- Changed the defaults of some Configuration settings:
-  - Changed the default of sourceEncoding ("encoding" earlier) to UTF-8 from the platform default charset.
-    Using the platform default charset was proven to be fragile in practice,
-    like applications could break when moved to another server if the application
-    was unwillingly relying on the default.
-  - Changed the default of templateExceptionHandler (template_exception_hander) to
-    TemplateExceptionHandler.RETHROW from DEBUG
-  - Changed the default of sqlDateAndTimeTimeZone (sqlDateAndTimeTimeZone) to
-    TimeZone.default() from null (where null meant falling back to the timeZone setting value)
-  - Changed the default of templateNameFormat (templateNameFormat) to what's equivalent to
-    FM2 DefaultTemplateNameFormat24. The old DefaultTemplateNameFormat was removed, and
-    DefaultTemplateNameFormat24 was renamed to DefaultTemplateNameFormat.
-- Removed the logTemplateExceptions (log_template_exceptions) setting. FreeMarker now
-  behaves as if it was false. When a FreeMarker method throws an exception, the
-  caller is responsible for either logging it or letting it bubble up.
+- Removed all classes with "main" methods that were part of freemarker.jar. Such tools should be separate artifacts,
+  not part of the library, and they are often classified as CWE-489 "Leftover Debug Code". The removed classes are:
+  freemarker.core.CommandLine, freemarker.ext.dom.Transform, freemarker.template.utility.ToCanonical
+- Removed classic_compatible (classicCompatible) setting, which was used to emulate some of the FreeMarker 1.x behavior
+- Removed utility TemplateModel-s that can very easily mean a security problem: freemarker.template.utility.Execute and
+  freemarker.template.utility.ObjectConstructor
+- Removed ResourceBundleLocalizedString and LocalizedString: Hardly anybody has discovered these, and they had no
+  JUnit coverage.
+- Deleted o.a.f.core.util.DOMNodeModel (it has noting to do with the standard XML support, o.a.f.core.model.dom)
+- Removed deprecated FMParser constructors.
+- Removed Template.templateLanguageVersion, as we solely rely on incompatibleImprovements instead.
+- Made TemplateModel classes used by the parser for literals Serializable. (Without this attribute values set in the
+  `#ftl` header wouldn't be always Serializable, which in turn will sabotage making Template-s Serializable in the
+  future.)
 - util.ObjectFactory was renamed to CommonSupplier, and its createObject() method was renamed to
   get(), to be more similar to the Java 8 API.
-- Removed long deprecated `#{}` interpolations. They are treated as plain static text now. (The
-  template converter tool translates these to `${}` interpolations. For example `#{x}` is simply 
-  translated to `${b}`, while `#{x; m1M3}` is translated to `${x?string('0.0##')}`).
-- #attempt doesn't create an additional debug level log entry when an exception is catched. It only
-  log an error level log (by default at least; see the `attemptExceptionReporter` setting)
-- You can't close #attempt/#recover with `</#recover>` anymore, only with `<#attempt>`. This was the
-  standard form in FM2 as well, and is consistent with how #if/#else works. (The template converter
-  tool does this conversion.)
-- Inside a #switch, #case can't be after #default anymore (this is actually a bug in FM2)
-  (The template converter can't fix this automatically, but reports it as an error.)
-- #else and #elseIf tags must be ended without "/", for example, <#else/> is illegal now, <#else> is legal.
-  (The template converter tool does this conversion.)
-- Spring Framework Support (freemarker-spring): FREEMARKER-54, FREEMARKER-55
-  - ConfigurationFactoryBean, a new Spring Framework's FactoryBean to create Configuration, using Builder.
-  - SpringResourceTemplateLoader, a new TemplateLoader to load templates from Spring Framework's Resources.
-  - New FreeMarkerView and FreeMarkerViewResolver for MVC support. FreeMarkerView supports TaglibFactory and other
-    models by default like FreemarkerServlet does.
 
+
+Build / development process changes
+-----------------------------------
+
+- Migrated buiding from Ant to Gradle. [TODO: This is only partially done; jar building, testing and javadoc works.]