freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [2/4] incubator-freemarker git commit: Made DefaultObjectWrapper immtutable (no more setters), also removed public constructors. Instead, instances are created with DefaultObjectWrapper.Builder.build(). Reworked DefaultObjectWrapper and ClassIntrospector
Date Fri, 17 Mar 2017 21:19:50 GMT
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java
index f64138a..fbe7d82 100644
--- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java
@@ -28,7 +28,7 @@ import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStr
 
 /**
  * Used as the parameter of {@link TemplateLookupStrategy#lookup(TemplateLookupContext)}.
- * You can't create instances of this, only receive them from FreeMarker.
+ * You can't invoke instances of this, only receive them from FreeMarker.
  * 
  * @since 2.3.22
  */

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/templateresolver/impl/TemplateLoaderBasedTemplateLookupResult.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/impl/TemplateLoaderBasedTemplateLookupResult.java b/src/main/java/org/apache/freemarker/core/templateresolver/impl/TemplateLoaderBasedTemplateLookupResult.java
index cfcbf44..fe7a54c 100644
--- a/src/main/java/org/apache/freemarker/core/templateresolver/impl/TemplateLoaderBasedTemplateLookupResult.java
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/impl/TemplateLoaderBasedTemplateLookupResult.java
@@ -26,9 +26,9 @@ import org.apache.freemarker.core.util._NullArgumentException;
 
 /**
  * Class of {@link TemplateLookupResult} instances created by {@link TemplateLoaderBasedTemplateLookupContext}. To
- * create instances of this inside your own {@link TemplateLoaderBasedTemplateLookupContext} subclass, call
+ * invoke instances of this inside your own {@link TemplateLoaderBasedTemplateLookupContext} subclass, call
  * {@link TemplateLoaderBasedTemplateLookupContext#createLookupResult(String, TemplateLoadingResult)} and
- * {@link TemplateLoaderBasedTemplateLookupContext#createNegativeLookupResult()}. You should not try to create instances
+ * {@link TemplateLoaderBasedTemplateLookupContext#createNegativeLookupResult()}. You should not try to invoke instances
  * anywhere else. Also, this class deliberately can't be subclassed (except inside FreeMarker).
  */
 public abstract class TemplateLoaderBasedTemplateLookupResult extends TemplateLookupResult {
@@ -38,7 +38,7 @@ public abstract class TemplateLoaderBasedTemplateLookupResult extends TemplateLo
         return NegativeTemplateLookupResult.INSTANCE;
     }
     
-    /** Used internally to create the appropriate kind of result from the parameters. */
+    /** Used internally to invoke the appropriate kind of result from the parameters. */
     static TemplateLoaderBasedTemplateLookupResult from(String templateSourceName, TemplateLoadingResult templateLoaderResult) {
         return templateLoaderResult.getStatus() != TemplateLoadingResultStatus.NOT_FOUND
                 ? new PositiveTemplateLookupResult(templateSourceName, templateLoaderResult)

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/util/BuilderBase.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/util/BuilderBase.java b/src/main/java/org/apache/freemarker/core/util/BuilderBase.java
new file mode 100644
index 0000000..c8eb12c
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/util/BuilderBase.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.freemarker.core.util;
+
+/**
+ * Common superclass of builders (used for implementing the builder pattern).
+ */
+public abstract class BuilderBase<ProductT, SelfT extends BuilderBase<ProductT, SelfT>> {
+
+    public abstract ProductT build();
+
+    @SuppressWarnings("unchecked")
+    protected SelfT self() {
+        return (SelfT) this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/util/ProductWrappingBuilder.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/util/ProductWrappingBuilder.java b/src/main/java/org/apache/freemarker/core/util/ProductWrappingBuilder.java
new file mode 100644
index 0000000..7c100bb
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/util/ProductWrappingBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.freemarker.core.util;
+
+/**
+ * A builder that encloses an already built product. {@link #build()} will always return the same product object.
+ */
+public class ProductWrappingBuilder<ProductT, SelfT extends ProductWrappingBuilder<ProductT, SelfT>>
+        extends BuilderBase<ProductT, SelfT> {
+
+    private final ProductT product;
+
+    public ProductWrappingBuilder(ProductT product) {
+        _NullArgumentException.check("product", product);
+        this.product = product;
+    }
+
+    @Override
+    public ProductT build() {
+        return product;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/util/WriteProtectable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/util/WriteProtectable.java b/src/main/java/org/apache/freemarker/core/util/WriteProtectable.java
deleted file mode 100644
index dc94cb8..0000000
--- a/src/main/java/org/apache/freemarker/core/util/WriteProtectable.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.util;
-
-/**
- * Implemented by objects that can be made <em>permanently</em> read-only. This usually meant to freeze the
- * configuration JavaBean properties, so that the object can be safely shared among independently developed components.
- * 
- * @since 2.3.21
- */
-public interface WriteProtectable {
-
-    /**
-     * Makes this object permanently read-only.
-     */
-    void writeProtect();
-    
-    boolean isWriteProtected();
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/util/_DateUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/util/_DateUtil.java b/src/main/java/org/apache/freemarker/core/util/_DateUtil.java
index 560fec9..0cf2fea 100644
--- a/src/main/java/org/apache/freemarker/core/util/_DateUtil.java
+++ b/src/main/java/org/apache/freemarker/core/util/_DateUtil.java
@@ -235,7 +235,7 @@ public class _DateUtil {
      *        that although date-only formats has no time zone offset part,
      *        the result still depends on the time zone, as days start and end
      *        at different points on the time line in different zones.      
-     * @param calendarFactory the factory that will create the calendar used
+     * @param calendarFactory the factory that will invoke the calendar used
      *        internally for calculations. The point of this parameter is that
      *        creating a new calendar is relatively expensive, so it's desirable
      *        to reuse calendars and only set their time and zone. (This was

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTargetTemplateValueFormatException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTargetTemplateValueFormatException.java b/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTargetTemplateValueFormatException.java
index 4ce5461..b4625a4 100644
--- a/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTargetTemplateValueFormatException.java
+++ b/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTargetTemplateValueFormatException.java
@@ -21,7 +21,7 @@ package org.apache.freemarker.core.valueformat.impl;
 import org.apache.freemarker.core.valueformat.TemplateValueFormatException;
 
 /**
- * Can't create a template format that the template format refers to (typically thrown by alias template formats).
+ * Can't invoke a template format that the template format refers to (typically thrown by alias template formats).
  * 
  * @since 2.3.24
  */

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateDateFormatFactory.java b/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateDateFormatFactory.java
index b366791..a964bc2 100644
--- a/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateDateFormatFactory.java
+++ b/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateDateFormatFactory.java
@@ -89,7 +89,7 @@ public final class AliasTemplateDateFormatFactory extends TemplateDateFormatFact
             }
             return env.getTemplateDateFormat(targetFormatString, dateType, locale, timeZone, zonelessInput);
         } catch (TemplateValueFormatException e) {
-            throw new AliasTargetTemplateValueFormatException("Failed to create format based on target format string,  "
+            throw new AliasTargetTemplateValueFormatException("Failed to invoke format based on target format string,  "
                     + _StringUtil.jQuote(params) + ". Reason given: " + e.getMessage(), e);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateNumberFormatFactory.java b/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateNumberFormatFactory.java
index 2c2a9b0..72e8abd 100644
--- a/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateNumberFormatFactory.java
+++ b/src/main/java/org/apache/freemarker/core/valueformat/impl/AliasTemplateNumberFormatFactory.java
@@ -88,7 +88,7 @@ public final class AliasTemplateNumberFormatFactory extends TemplateNumberFormat
             }
             return env.getTemplateNumberFormat(targetFormatString, locale);
         } catch (TemplateValueFormatException e) {
-            throw new AliasTargetTemplateValueFormatException("Failed to create format based on target format string,  "
+            throw new AliasTargetTemplateValueFormatException("Failed to invoke format based on target format string,  "
                     + _StringUtil.jQuote(params) + ". Reason given: " + e.getMessage(), e);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/core/valueformat/impl/JavaTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/valueformat/impl/JavaTemplateNumberFormatFactory.java b/src/main/java/org/apache/freemarker/core/valueformat/impl/JavaTemplateNumberFormatFactory.java
index 41dd373..cf292df 100644
--- a/src/main/java/org/apache/freemarker/core/valueformat/impl/JavaTemplateNumberFormatFactory.java
+++ b/src/main/java/org/apache/freemarker/core/valueformat/impl/JavaTemplateNumberFormatFactory.java
@@ -100,7 +100,7 @@ public class JavaTemplateNumberFormatFactory extends TemplateNumberFormatFactory
             }
         }  // if cache miss
         
-        // JFormat-s aren't thread-safe; must clone it
+        // JFormat-s aren't thread-safe; must deepClone it
         jFormat = (NumberFormat) jFormat.clone();
         
         return new JavaTemplateNumberFormat(jFormat, params);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java
index 95b139e..0fc7cfa 100644
--- a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java
+++ b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java
@@ -752,14 +752,14 @@ public class FreemarkerServlet extends HttpServlet {
     }
 
     /**
-     * Create the template loader. The default implementation will create a {@link ClassTemplateLoader} if the template
+     * Create the template loader. The default implementation will invoke a {@link ClassTemplateLoader} if the template
      * path starts with {@code "class://"}, a {@link FileTemplateLoader} if the template path starts with
      * {@code "file://"}, and a {@link WebAppTemplateLoader} otherwise. Also, if
      * {@link Configuration#Configuration(org.apache.freemarker.core.Version) incompatible_improvements} is 2.3.22 or higher,
-     * it will create a {@link MultiTemplateLoader} if the template path starts with {@code "["}.
+     * it will invoke a {@link MultiTemplateLoader} if the template path starts with {@code "["}.
      * 
      * @param templatePath
-     *            the template path to create a loader for
+     *            the template path to invoke a loader for
      * @return a newly created template loader
      */
     protected TemplateLoader createTemplateLoader(String templatePath) throws IOException {
@@ -1082,7 +1082,7 @@ public class FreemarkerServlet extends HttpServlet {
     }
 
     /**
-     * Called to create the {@link TaglibFactory} once per servlet context.
+     * Called to invoke the {@link TaglibFactory} once per servlet context.
      * The default implementation configures it based on the servlet-init parameters and various other environmental
      * settings, so if you override this method, you should call super, then adjust the result.
      * 
@@ -1276,7 +1276,7 @@ public class FreemarkerServlet extends HttpServlet {
     }
     
     /**
-     * Called from {@link #init()} to create the {@link ObjectWrapper}; to customzie this aspect, in most cases you
+     * Called from {@link #init()} to invoke the {@link ObjectWrapper}; to customzie this aspect, in most cases you
      * should override {@link #createDefaultObjectWrapper()} instead. Overriding this method is necessary when you want
      * to customize how the {@link ObjectWrapper} is created <em>from the init-param values</em>, or you want to do some
      * post-processing (like checking) on the created {@link ObjectWrapper}. To customize init-param interpretation,
@@ -1301,7 +1301,7 @@ public class FreemarkerServlet extends HttpServlet {
                         + DEPR_INITPARAM_OBJECT_WRAPPER);
             }
             if (DEPR_INITPARAM_WRAPPER_RESTRICTED.equals(wrapper)) {
-                return new RestrictedObjectWrapper(Configuration.VERSION_3_0_0);
+                return new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
             }
             return createDefaultObjectWrapper();
         } else {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/servlet/IncludePage.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/servlet/IncludePage.java b/src/main/java/org/apache/freemarker/servlet/IncludePage.java
index 30456ca..608f1bb 100644
--- a/src/main/java/org/apache/freemarker/servlet/IncludePage.java
+++ b/src/main/java/org/apache/freemarker/servlet/IncludePage.java
@@ -100,7 +100,7 @@ public class IncludePage implements TemplateDirectiveModel {
             final PrintWriter printWriter = (envOut instanceof PrintWriter) ?
                 (PrintWriter) envOut :
                 new PrintWriter(envOut); 
-            // Otherwise, create a response wrapper that will pass the
+            // Otherwise, invoke a response wrapper that will pass the
             // env writer, potentially first wrapping it in a print
             // writer when it ain't one already.
             wrappedResponse = new HttpServletResponseWrapper(response) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java b/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
index a0d2cb6..b005260 100644
--- a/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
+++ b/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
@@ -37,7 +37,7 @@ import org.apache.freemarker.core.util.BugException;
 import org.apache.freemarker.core.util._ClassUtil;
 
 /**
- * Used when a custom JSP tag and an EL function uses the same name in a tag library, to create a single FTL value from
+ * Used when a custom JSP tag and an EL function uses the same name in a tag library, to invoke a single FTL value from
  * the two. As FTL as no separate namespace for "tags" and functions, both aspect has to be implemented by the same
  * value.
  * 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java b/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
index f38918d..ec4a5d0 100644
--- a/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
+++ b/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
@@ -1809,7 +1809,7 @@ public class TaglibFactory implements TemplateHashModel {
                         listener = listenerClass.newInstance();
                     } catch (Exception e) {
                         throw new TldParsingSAXException(
-                                "Failed to create new instantiate from listener class " + listenerClassCData,
+                                "Failed to invoke new instantiate from listener class " + listenerClassCData,
                                 locator,
                                 e);
                     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/main/java/org/apache/freemarker/servlet/jsp/_FreeMarkerPageContext21.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/servlet/jsp/_FreeMarkerPageContext21.java b/src/main/java/org/apache/freemarker/servlet/jsp/_FreeMarkerPageContext21.java
index f1d1fd0..a146c01 100644
--- a/src/main/java/org/apache/freemarker/servlet/jsp/_FreeMarkerPageContext21.java
+++ b/src/main/java/org/apache/freemarker/servlet/jsp/_FreeMarkerPageContext21.java
@@ -110,7 +110,7 @@ public class _FreeMarkerPageContext21 extends FreeMarkerPageContext {
                 elContext.putContext(JspContext.class, this);
             } else {
                 throw new UnsupportedOperationException(
-                        "Can not create an ELContext using a foreign JspApplicationContext (of class "
+                        "Can not invoke an ELContext using a foreign JspApplicationContext (of class "
                         + _ClassUtil.getShortClassNameOfObject(jspctx) + ").\n" +
                         "Hint: The cause of this is often that you are trying to use JSTL tags/functions in FTL. "
                         + "In that case, know that that's not really suppored, and you are supposed to use FTL "

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/manual/en_US/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/src/manual/en_US/FM3-CHANGE-LOG.txt b/src/manual/en_US/FM3-CHANGE-LOG.txt
index f59ed0b..e15d2b5 100644
--- a/src/manual/en_US/FM3-CHANGE-LOG.txt
+++ b/src/manual/en_US/FM3-CHANGE-LOG.txt
@@ -150,4 +150,10 @@ the FreeMarer 3 changelog here:
   read method can still be called as an usual method (as `myObj.getFoo(index)`). These changes were made because building on the
   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.)
\ No newline at end of file
+  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 not immutable (has no setter methods), and can only be constructed with DefaultObjectWrapper.Builder.n
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/ASTPrinter.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/ASTPrinter.java b/src/test/java/org/apache/freemarker/core/ASTPrinter.java
index a80e1f1..10701cf 100644
--- a/src/test/java/org/apache/freemarker/core/ASTPrinter.java
+++ b/src/test/java/org/apache/freemarker/core/ASTPrinter.java
@@ -195,7 +195,7 @@ public class ASTPrinter {
     private void save(String astStr, File file) throws IOException {
         File parentDir = file.getParentFile();
         if (!parentDir.isDirectory() && !parentDir.mkdirs()) {
-            throw new IOException("Failed to create parent directory: " + parentDir);
+            throw new IOException("Failed to invoke parent directory: " + parentDir);
         }
         
         Writer w = new BufferedWriter(new FileWriter(file));

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
index 0ad4773..6ae7396 100644
--- a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
+++ b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
@@ -40,7 +40,6 @@ import java.util.TimeZone;
 import org.apache.freemarker.core.model.TemplateModelException;
 import org.apache.freemarker.core.model.TemplateScalarModel;
 import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapperBuilder;
 import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
 import org.apache.freemarker.core.model.impl.SimpleScalar;
 import org.apache.freemarker.core.outputformat.MarkupOutputFormat;
@@ -109,7 +108,7 @@ public class ConfigurationTest extends TestCase {
         assertFalse(cfg.isObjectWrapperExplicitlySet());
         assertSame(Configuration.getDefaultObjectWrapper(Configuration.VERSION_3_0_0), cfg.getObjectWrapper());
         //
-        RestrictedObjectWrapper ow = new RestrictedObjectWrapper(Configuration.VERSION_3_0_0);
+        RestrictedObjectWrapper ow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
         cfg.setObjectWrapper(ow);
         assertTrue(cfg.isObjectWrapperExplicitlySet());
         assertSame(ow, cfg.getObjectWrapper());
@@ -1075,7 +1074,7 @@ public class ConfigurationTest extends TestCase {
         cfg.setSharedVariable("b", "bbLegacy");
         
         // Cause re-wrapping of variables added via setSharedVaribles:
-        cfg.setObjectWrapper(new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build());
+        cfg.setObjectWrapper(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
 
         {
             TemplateScalarModel aVal = (TemplateScalarModel) cfg.getSharedVariable("a");

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java b/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
index 9df5840..d35003d 100644
--- a/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
+++ b/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
@@ -78,7 +78,7 @@ public class IncludeAndImportTest extends TemplateTest {
     
     @Test
     public void importInMainCreatesGlobalBugfix() throws IOException, TemplateException {
-        // An import in the main namespace should create a global variable, even if the imported library was already
+        // An import in the main namespace should invoke a global variable, even if the imported library was already
         // initialized elsewhere.
         String ftl = "<#import 'lib3ImportsLib1.ftl' as lib3>${lib1Cnt} ${.main.lib1???c} ${.globals.lib1???c}, "
         + "<#import 'lib1.ftl' as lib1>${lib1Cnt} ${.main.lib1???c} ${.globals.lib1???c}";

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java b/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
index 646b1dd..08fcee2 100644
--- a/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
+++ b/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
@@ -22,13 +22,12 @@ import java.util.Arrays;
 import java.util.Iterator;
 
 import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapperBuilder;
 import org.apache.freemarker.test.TemplateTest;
 import org.junit.Test;
 
 public class IteratorIssuesTest extends TemplateTest {
 
-    private static final DefaultObjectWrapper OW = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build();
+    private static final DefaultObjectWrapper OW = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
 
     private static final String FTL_HAS_CONTENT_AND_LIST
             = "<#if it?hasContent><#list it as i>${i}</#list><#else>empty</#if>";

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/ListErrorsTest.java b/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
index b798a35..05bac4f 100644
--- a/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
+++ b/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
@@ -121,7 +121,7 @@ public class ListErrorsTest extends TemplateTest {
     @Test
     public void testNonEx2NonStringKey() throws IOException, TemplateException {
         addToDataModel("m", new Listables.NonEx2MapAdapter(ImmutableMap.of("k1", "v1", 2, "v2"),
-                new DefaultObjectWrapper(Configuration.VERSION_3_0_0)));
+                new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build()));
         assertOutput("<#list m?keys as k>${k};</#list>", "k1;2;");
         assertErrorContains("<#list m as k, v></#list>",
                 "string", "number", ".TemplateHashModelEx2");

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java b/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
index 5404af8..1b36efe 100644
--- a/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
+++ b/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
@@ -49,7 +49,6 @@ import org.apache.freemarker.core.templateresolver.TemplateLoadingResult;
 import org.apache.freemarker.core.templateresolver.TemplateLoadingSource;
 import org.apache.freemarker.core.templateresolver.impl.MruCacheStorage;
 import org.apache.freemarker.core.userpkg.PublicWithMixedConstructors;
-import org.apache.freemarker.core.util.WriteProtectable;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableList;
@@ -236,31 +235,6 @@ public class ObjectBuilderSettingsTest {
             assertNotSame(TestBean5.INSTANCE, res);
         }
     }
-    
-    @Test
-    public void writeProtectionTest() throws Exception {
-        {
-            TestBean3 res = (TestBean3) _ObjectBuilderSettingEvaluator.eval(
-                    "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean3(x = 1)",
-                    Object.class, false, _SettingEvaluationEnvironment.getCurrent());
-            assertEquals(1, res.x);
-            assertTrue(res.isWriteProtected());
-            try {
-                res.setX(2);
-                fail();
-            } catch (IllegalStateException e) {
-                // expected
-            }
-        }
-        
-        {
-            TestBean3 res = (TestBean3) _ObjectBuilderSettingEvaluator.eval(
-                    "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean3",
-                    Object.class, false, _SettingEvaluationEnvironment.getCurrent());
-            assertEquals(0, res.x);
-            assertTrue(res.isWriteProtected()); // Still uses a builder
-        }
-    }
 
     @Test
     public void stringLiteralsTest() throws Exception {
@@ -398,7 +372,6 @@ public class ObjectBuilderSettingsTest {
                     "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyTemplateLoader()");
             cfg.setSettings(props);
             assertEquals(DefaultObjectWrapper.class, cfg.getObjectWrapper().getClass());
-            assertTrue(((WriteProtectable) cfg.getObjectWrapper()).isWriteProtected());
             assertEquals(
                     Configuration.VERSION_3_0_0, ((DefaultObjectWrapper) cfg.getObjectWrapper()).getIncompatibleImprovements());
             assertEquals(DummyArithmeticEngine.class, cfg.getArithmeticEngine().getClass());
@@ -422,7 +395,6 @@ public class ObjectBuilderSettingsTest {
                     "allows_nothing");
             cfg.setSettings(props);
             assertEquals(DefaultObjectWrapper.class, cfg.getObjectWrapper().getClass());
-            assertTrue(((WriteProtectable) cfg.getObjectWrapper()).isWriteProtected());
             assertEquals(1, ((DummyArithmeticEngine) cfg.getArithmeticEngine()).getX());
             assertEquals(1, ((DummyTemplateExceptionHandler) cfg.getTemplateExceptionHandler()).getX());
             assertEquals(Configuration.VERSION_3_0_0,
@@ -441,7 +413,6 @@ public class ObjectBuilderSettingsTest {
             assertEquals(DefaultObjectWrapper.class, cfg.getObjectWrapper().getClass());
             assertSame(BigDecimalArithmeticEngine.INSTANCE, cfg.getArithmeticEngine());
             assertSame(TemplateExceptionHandler.RETHROW_HANDLER, cfg.getTemplateExceptionHandler());
-            assertTrue(((WriteProtectable) cfg.getObjectWrapper()).isWriteProtected());
             assertEquals(Configuration.VERSION_3_0_0,
                     ((DefaultObjectWrapper) cfg.getObjectWrapper()).getIncompatibleImprovements());
         }
@@ -451,7 +422,6 @@ public class ObjectBuilderSettingsTest {
             props.setProperty(Configurable.OBJECT_WRAPPER_KEY, "DefaultObjectWrapper(3.0.0)");
             cfg.setSettings(props);
             assertEquals(DefaultObjectWrapper.class, cfg.getObjectWrapper().getClass());
-            assertTrue(((WriteProtectable) cfg.getObjectWrapper()).isWriteProtected());
             assertEquals(
                     Configuration.VERSION_3_0_0,
                     ((DefaultObjectWrapper) cfg.getObjectWrapper()).getIncompatibleImprovements());
@@ -1120,28 +1090,15 @@ public class ObjectBuilderSettingsTest {
         
     }
 
-    public static class TestBean3 implements WriteProtectable {
-        
-        private boolean writeProtected;
+    public static class TestBean3 {
         
         private int x;
 
-        @Override
-        public void writeProtect() {
-            writeProtected = true;
-        }
-
-        @Override
-        public boolean isWriteProtected() {
-            return writeProtected;
-        }
-
         public int getX() {
             return x;
         }
 
         public void setX(int x) {
-            if (writeProtected) throw new IllegalStateException();
             this.x = x;
         }
         

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java b/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
index d76a31e..702a254 100644
--- a/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
+++ b/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
@@ -46,7 +46,7 @@ public class RestrictedObjectWrapperTest {
     @Test
     public void testBasics() throws TemplateModelException {
         PostConstruct.class.toString();
-        RestrictedObjectWrapper ow = new RestrictedObjectWrapper(Configuration.VERSION_3_0_0);
+        RestrictedObjectWrapper ow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
         testCustomizationCommonPart(ow);
         assertTrue(ow.wrap(Collections.emptyMap()) instanceof DefaultMapAdapter);
         assertTrue(ow.wrap(Collections.emptyList()) instanceof DefaultListAdapter);
@@ -56,8 +56,6 @@ public class RestrictedObjectWrapperTest {
 
     @SuppressWarnings("boxing")
     private void testCustomizationCommonPart(RestrictedObjectWrapper ow) throws TemplateModelException {
-        assertFalse(ow.isWriteProtected());
-        
         assertTrue(ow.wrap("x") instanceof SimpleScalar);
         assertTrue(ow.wrap(1.5) instanceof SimpleNumber);
         assertTrue(ow.wrap(new Date()) instanceof SimpleDate);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java b/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
new file mode 100644
index 0000000..43ff3bf
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.freemarker.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateCollectionModel;
+import org.apache.freemarker.core.model.TemplateCollectionModelEx;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateHashModelEx2;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateModelWithAPISupport;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class RestrictedObjetWrapperTest {
+    
+    @Test
+    public void testDoesNotAllowAPIBuiltin() throws TemplateModelException {
+        RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+        
+        TemplateModelWithAPISupport map = (TemplateModelWithAPISupport) sow.wrap(new HashMap());
+        try {
+            map.getAPI();
+            fail();
+        } catch (TemplateException e) {
+            assertThat(e.getMessage(), containsString("?api"));
+        }
+    }
+
+    @SuppressWarnings("boxing")
+    @Test
+    public void testCanWrapBasicTypes() throws TemplateModelException {
+        RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+        assertTrue(sow.wrap("s") instanceof TemplateScalarModel);
+        assertTrue(sow.wrap(1) instanceof TemplateNumberModel);
+        assertTrue(sow.wrap(true) instanceof TemplateBooleanModel);
+        assertTrue(sow.wrap(new Date()) instanceof TemplateDateModel);
+        assertTrue(sow.wrap(new ArrayList()) instanceof TemplateSequenceModel);
+        assertTrue(sow.wrap(new String[0]) instanceof TemplateSequenceModel);
+        assertTrue(sow.wrap(new ArrayList().iterator()) instanceof TemplateCollectionModel);
+        assertTrue(sow.wrap(new HashSet()) instanceof TemplateCollectionModelEx);
+        assertTrue(sow.wrap(new HashMap()) instanceof TemplateHashModelEx2);
+        assertNull(sow.wrap(null));
+    }
+    
+    @Test
+    public void testWontWrapDOM() throws SAXException, IOException, ParserConfigurationException,
+            TemplateModelException {
+        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+        InputSource is = new InputSource();
+        is.setCharacterStream(new StringReader("<doc><sub a='1' /></doc>"));
+        Document doc = db.parse(is);
+        
+        RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+        try {
+            sow.wrap(doc);
+            fail();
+        } catch (TemplateModelException e) {
+            assertThat(e.getMessage(), containsString("won't wrap"));
+        }
+    }
+    
+    @Test
+    public void testWontWrapGenericObjects() {
+        RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+        try {
+            sow.wrap(new File("/x"));
+            fail();
+        } catch (TemplateModelException e) {
+            assertThat(e.getMessage(), containsString("won't wrap"));
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/SimpleObjetWrapperTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/SimpleObjetWrapperTest.java b/src/test/java/org/apache/freemarker/core/SimpleObjetWrapperTest.java
deleted file mode 100644
index 040695d..0000000
--- a/src/test/java/org/apache/freemarker/core/SimpleObjetWrapperTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateCollectionModel;
-import org.apache.freemarker.core.model.TemplateCollectionModelEx;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateHashModelEx2;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateModelWithAPISupport;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.TemplateSequenceModel;
-import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-public class SimpleObjetWrapperTest {
-    
-    @Test
-    public void testDoesNotAllowAPIBuiltin() throws TemplateModelException {
-        RestrictedObjectWrapper sow = new RestrictedObjectWrapper(Configuration.VERSION_3_0_0);
-        
-        TemplateModelWithAPISupport map = (TemplateModelWithAPISupport) sow.wrap(new HashMap());
-        try {
-            map.getAPI();
-            fail();
-        } catch (TemplateException e) {
-            assertThat(e.getMessage(), containsString("?api"));
-        }
-    }
-
-    @SuppressWarnings("boxing")
-    @Test
-    public void testCanWrapBasicTypes() throws TemplateModelException {
-        RestrictedObjectWrapper sow = new RestrictedObjectWrapper(Configuration.VERSION_3_0_0);
-        assertTrue(sow.wrap("s") instanceof TemplateScalarModel);
-        assertTrue(sow.wrap(1) instanceof TemplateNumberModel);
-        assertTrue(sow.wrap(true) instanceof TemplateBooleanModel);
-        assertTrue(sow.wrap(new Date()) instanceof TemplateDateModel);
-        assertTrue(sow.wrap(new ArrayList()) instanceof TemplateSequenceModel);
-        assertTrue(sow.wrap(new String[0]) instanceof TemplateSequenceModel);
-        assertTrue(sow.wrap(new ArrayList().iterator()) instanceof TemplateCollectionModel);
-        assertTrue(sow.wrap(new HashSet()) instanceof TemplateCollectionModelEx);
-        assertTrue(sow.wrap(new HashMap()) instanceof TemplateHashModelEx2);
-        assertNull(sow.wrap(null));
-    }
-    
-    @Test
-    public void testWontWrapDOM() throws SAXException, IOException, ParserConfigurationException,
-            TemplateModelException {
-        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-        InputSource is = new InputSource();
-        is.setCharacterStream(new StringReader("<doc><sub a='1' /></doc>"));
-        Document doc = db.parse(is);
-        
-        RestrictedObjectWrapper sow = new RestrictedObjectWrapper(Configuration.VERSION_3_0_0);
-        try {
-            sow.wrap(doc);
-            fail();
-        } catch (TemplateModelException e) {
-            assertThat(e.getMessage(), containsString("won't wrap"));
-        }
-    }
-    
-    @Test
-    public void testWontWrapGenericObjects() {
-        RestrictedObjectWrapper sow = new RestrictedObjectWrapper(Configuration.VERSION_3_0_0);
-        try {
-            sow.wrap(new File("/x"));
-            fail();
-        } catch (TemplateModelException e) {
-            assertThat(e.getMessage(), containsString("won't wrap"));
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java b/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
index 551912f..07b39e4 100644
--- a/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
+++ b/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
@@ -160,7 +160,7 @@ public class TagSyntaxVariationsTest extends TestCase {
             t = new Template("string", new StringReader(template), cfg);
         } catch (ParseException e) {
             if (expected != null) {
-                fail("Couldn't create Template from "
+                fail("Couldn't invoke Template from "
                         + _StringUtil.jQuote(template) + ": " + e);
             } else {
                 return;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java b/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
index bf3587e..7943a2d 100644
--- a/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
+++ b/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
@@ -172,7 +172,7 @@ public class TemplateConfigurationTest {
         SETTING_ASSIGNMENTS.put("logTemplateExceptions", true);
         SETTING_ASSIGNMENTS.put("newBuiltinClassResolver", TemplateClassResolver.ALLOWS_NOTHING_RESOLVER);
         SETTING_ASSIGNMENTS.put("numberFormat", "0.0000");
-        SETTING_ASSIGNMENTS.put("objectWrapper", new RestrictedObjectWrapper(ICI));
+        SETTING_ASSIGNMENTS.put("objectWrapper", new RestrictedObjectWrapper.Builder(ICI).build());
         SETTING_ASSIGNMENTS.put("outputEncoding", "utf-16");
         SETTING_ASSIGNMENTS.put("showErrorTips", false);
         SETTING_ASSIGNMENTS.put("templateExceptionHandler", TemplateExceptionHandler.IGNORE_HANDLER);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java b/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
index 250da24..bdb9a56 100644
--- a/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
+++ b/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
@@ -35,7 +35,8 @@ public abstract class AbstractParallelIntrospectionTest extends TestCase {
     private static final int ITERATIONS = 20000;
     private static final double CACHE_CLEARING_CHANCE = 0.01;
     
-    private DefaultObjectWrapper ow = new DefaultObjectWrapper(Configuration.VERSION_3_0_0);
+    private DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+            .usePrivateCaches(true).build();
     
     public AbstractParallelIntrospectionTest(String name) {
         super(name);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
index 250c734..0ed6e7c 100644
--- a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
+++ b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
@@ -21,10 +21,11 @@ package org.apache.freemarker.core.model.impl;
 
 import org.apache.freemarker.core.Configuration;
 
-public class DefaultObjectWrapperDesc extends DefaultObjectWrapperWithSortedMethods {
+public class DefaultObjectWrapperDesc extends DefaultObjectWrapper {
 
     public DefaultObjectWrapperDesc() {
-        super(Configuration.VERSION_3_0_0, true);
+        super(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+                .methodSorter(new AlphabeticalMethodSorter(true)), true);
     }
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
index bf25611..eb2cda0 100644
--- a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
+++ b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
@@ -21,10 +21,11 @@ package org.apache.freemarker.core.model.impl;
 
 import org.apache.freemarker.core.Configuration;
 
-public class DefaultObjectWrapperInc extends DefaultObjectWrapperWithSortedMethods {
+public class DefaultObjectWrapperInc extends DefaultObjectWrapper {
 
     public DefaultObjectWrapperInc() {
-        super(Configuration.VERSION_3_0_0, false);
+        super(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+                .methodSorter(new AlphabeticalMethodSorter(false)), true);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
index 270a39e..5c2f653 100644
--- a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
+++ b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
@@ -30,41 +30,10 @@ public class DefaultObjectWrapperModelFactoryRegistrationTest {
 
     @Test
     public void introspectionSettingChanges() {
-        DefaultObjectWrapper ow = new DefaultObjectWrapper(Configuration.VERSION_3_0_0);
+        DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).usePrivateCaches(true)
+                .build();
         ClassIntrospector ci1 = ow.getClassIntrospector();
         checkRegisteredModelFactories(ci1, ow.getStaticModels(), ow.getEnumModels());
-
-        ow.setExposeFields(true);
-        ClassIntrospector ci2 = ow.getClassIntrospector();
-        assertNotSame(ci1, ci2);
-        checkRegisteredModelFactories(ci1);
-        checkRegisteredModelFactories(ci2, ow.getStaticModels(), ow.getEnumModels());
-
-        ow.setExposureLevel(DefaultObjectWrapper.EXPOSE_ALL);
-        ClassIntrospector ci3 = ow.getClassIntrospector();
-        assertNotSame(ci2, ci3);
-        checkRegisteredModelFactories(ci2);
-        checkRegisteredModelFactories(ci3, ow.getStaticModels(), ow.getEnumModels());
-
-        MethodAppearanceFineTuner maf = new MethodAppearanceFineTuner() {
-            @Override
-            public void process(DecisionInput in, Decision out) {
-                // nop
-            }
-        };
-        ow.setMethodAppearanceFineTuner(maf);
-        ClassIntrospector ci4 = ow.getClassIntrospector();
-        assertNotSame(ci3, ci4);
-        checkRegisteredModelFactories(ci3);
-        checkRegisteredModelFactories(ci4, ow.getStaticModels(), ow.getEnumModels());
-
-        ow.setExposeFields(true);
-        assertSame(ci4, ow.getClassIntrospector());
-        ow.setExposureLevel(DefaultObjectWrapper.EXPOSE_ALL);
-        assertSame(ci4, ow.getClassIntrospector());
-        ow.setMethodAppearanceFineTuner(maf);
-        assertSame(ci4, ow.getClassIntrospector());
-        checkRegisteredModelFactories(ci4, ow.getStaticModels(), ow.getEnumModels());
     }
 
     private void checkRegisteredModelFactories(ClassIntrospector ci, Object... expected) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperReadOnlyTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperReadOnlyTest.java b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperReadOnlyTest.java
deleted file mode 100644
index 72e9bd8..0000000
--- a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperReadOnlyTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.model.impl;
-
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.util.WriteProtectable;
-import org.apache.freemarker.core.util._ClassUtil;
-
-import junit.framework.TestCase;
-
-/**
- * Tests if all JavaBean properties of {@link DefaultObjectWrapper} are locked by
- * {@link WriteProtectable#writeProtect()}.
- */
-public class DefaultObjectWrapperReadOnlyTest extends TestCase {
-
-    private static final String EXPECTED_MESSAGE_PART = "write protected";
-
-    public DefaultObjectWrapperReadOnlyTest(String name) {
-        super(name);
-    }
-    
-    public void testDefaultObjectWrapper() throws Exception {
-        DefaultObjectWrapper ow = new DefaultObjectWrapper(Configuration.VERSION_3_0_0);
-        ow.writeProtect();
-        checkAllPropertiesReadOnly(ow);
-    }
-    
-    private void checkAllPropertiesReadOnly(Object o) throws Exception {
-        BeanInfo bi = Introspector.getBeanInfo(o.getClass());
-        for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
-            Method setter = pd.getWriteMethod();
-            if (setter != null) {
-                Class t = pd.getPropertyType();
-                
-                Object val;
-                if (_ClassUtil.isNumerical(t)) {
-                    val = Byte.valueOf((byte) 1);
-                } else if (t == boolean.class) {
-                    val = Boolean.TRUE;
-                } else if (t == char.class) {
-                    val = Character.valueOf('c');
-                } else if (t.isAssignableFrom(String.class)) {
-                    val = "s";
-                } else {
-                    val = null;
-                }
-                try {
-                    setter.invoke(o, val);
-                    fail("This setter should have failed as the property should be read-only now: " + setter);
-                } catch (InvocationTargetException e) {
-                    Throwable target = e.getTargetException();
-                    if (!(target instanceof IllegalStateException
-                            && target.getMessage() != null
-                            && target.getMessage().contains(EXPECTED_MESSAGE_PART))) {
-                        fail("Expected IllegalStateException with message containing \"" + EXPECTED_MESSAGE_PART
-                                + "\", got this instead: " + target);
-                    }
-                }
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
index cf84333..355aa12 100644
--- a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
+++ b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
@@ -46,23 +46,23 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
     
     @Override
     protected void setUp() throws Exception {
-        DefaultObjectWrapperBuilder.clearInstanceCache();
+        DefaultObjectWrapper.Builder.clearInstanceCache();
     }
 
     public void testBuilderEqualsAndHash() throws Exception {
-        assertEquals(Configuration.VERSION_3_0_0, new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).getIncompatibleImprovements());
+        assertEquals(Configuration.VERSION_3_0_0, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).getIncompatibleImprovements());
         try {
-            new DefaultObjectWrapperBuilder(TestUtil.getClosestFutureVersion());
+            new DefaultObjectWrapper.Builder(TestUtil.getClosestFutureVersion());
             fail("Maybe you need to update this test for the new FreeMarker version");
         } catch (IllegalArgumentException e) {
             assertThat(e.getMessage(), containsString("upgrade"));
         }
 
-        DefaultObjectWrapperBuilder builder1;
-        DefaultObjectWrapperBuilder builder2;
+        DefaultObjectWrapper.Builder builder1;
+        DefaultObjectWrapper.Builder builder2;
         
-        builder1 = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
-        builder2 = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+        builder1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+        builder2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
         assertEquals(builder1, builder2);
         
         builder1.setExposeFields(true);
@@ -134,7 +134,6 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
             assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
             assertSame(ow.getClass(), DefaultObjectWrapper.class);
             assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
-            assertTrue(ow.isWriteProtected());
             assertFalse(ow.isStrict());
             assertTrue(ow.getUseModelCache());
             assertEquals(TemplateDateModel.UNKNOWN, ow.getDefaultDateType());
@@ -142,14 +141,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
             assertTrue(ow.isClassIntrospectionCacheRestricted());
             assertNull(ow.getMethodAppearanceFineTuner());
             assertNull(ow.getMethodSorter());
-            
-            try {
-                ow.setExposeFields(true);  // can't modify the settings of a (potential) singleton
-                fail();
-            } catch (IllegalStateException e) {
-                assertThat(e.getMessage(), containsString("modify"));
-            }
-            
+
             assertSame(ow, getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, true));
             assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
             
@@ -161,7 +153,6 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
             assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
             assertSame(ow.getClass(), DefaultObjectWrapper.class);
             assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
-            assertTrue(ow.isWriteProtected());
             assertFalse(ow.getUseModelCache());
 
             assertSame(ow, getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, false));
@@ -170,7 +161,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
         
         {
-            DefaultObjectWrapperBuilder factory = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             factory.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
             DefaultObjectWrapper ow1 = factory.build();
             DefaultObjectWrapper ow2 = factory.build();
@@ -179,7 +170,6 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
             
             assertSame(ow1.getClass(), DefaultObjectWrapper.class);
             assertEquals(Configuration.VERSION_3_0_0, ow1.getIncompatibleImprovements());
-            assertTrue(ow1.isWriteProtected());
             assertEquals(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY, ow1.getExposureLevel());
             assertFalse(ow1.isStrict());
             assertEquals(TemplateDateModel.UNKNOWN, ow1.getDefaultDateType());
@@ -189,7 +179,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
         
         {
-            DefaultObjectWrapperBuilder factory = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             factory.setExposeFields(true);
             DefaultObjectWrapper ow1 = factory.build();
             DefaultObjectWrapper ow2 = factory.build();
@@ -198,17 +188,16 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
             
             assertSame(ow1.getClass(), DefaultObjectWrapper.class);
             assertEquals(Configuration.VERSION_3_0_0, ow1.getIncompatibleImprovements());
-            assertTrue(ow1.isWriteProtected());
             assertTrue(ow1.isExposeFields());
             
             hardReferences.add(ow1);
         }
         
         {
-            DefaultObjectWrapperBuilder factory = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             factory.setStrict(true);
             factory.setDefaultDateType(TemplateDateModel.DATETIME);
-            factory.setOuterIdentity(new RestrictedObjectWrapper(Configuration.VERSION_3_0_0));
+            factory.setOuterIdentity(new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
             DefaultObjectWrapper ow = factory.build();
             assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
             assertTrue(ow.isStrict());
@@ -220,7 +209,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         
         // Effect of reference and cache clearings:
         {
-            DefaultObjectWrapper bw1 = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build();
+            DefaultObjectWrapper bw1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
             assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
             assertEquals(5, getDefaultObjectWrapperNonClearedInstanceCacheSize());
             
@@ -228,23 +217,23 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
             assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
             assertEquals(0, getDefaultObjectWrapperNonClearedInstanceCacheSize());
             
-            DefaultObjectWrapper bw2 = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build();
+            DefaultObjectWrapper bw2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
             assertNotSame(bw1, bw2);
             assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
             assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
             
-            assertSame(bw2, new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build());
+            assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
             assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
             
             clearDefaultObjectWrapperInstanceCacheReferences(true);
-            DefaultObjectWrapper bw3 = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build();
+            DefaultObjectWrapper bw3 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
             assertNotSame(bw2, bw3);
             assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
             assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
         }
 
         {
-            DefaultObjectWrapperBuilder factory = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             factory.setUseModelCache(true);
             DefaultObjectWrapper ow = factory.build();
             assertTrue(ow.getUseModelCache());
@@ -257,7 +246,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
     }
     
     private DefaultObjectWrapper getDefaultObjectWrapperWithSetting(Version ici, boolean useModelCache) {
-        DefaultObjectWrapperBuilder f = new DefaultObjectWrapperBuilder(ici);
+        DefaultObjectWrapper.Builder f = new DefaultObjectWrapper.Builder(ici);
         f.setUseModelCache(useModelCache);
         return f.build();
     }
@@ -267,7 +256,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         
         assertEquals(0, getDefaultObjectWrapperInstanceCacheSize());
         
-        DefaultObjectWrapper bw1 = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build();
+        DefaultObjectWrapper bw1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
         assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
         hardReferences.add(bw1);
         
@@ -278,25 +267,25 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         DefaultObjectWrapper bw2;
         Thread.currentThread().setContextClassLoader(newTCCL);
         try {
-            bw2 = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build();
+            bw2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
             assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
             hardReferences.add(bw2);
             
             assertNotSame(bw1, bw2);
-            assertSame(bw2, new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build());
+            assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
         } finally {
             Thread.currentThread().setContextClassLoader(oldTCCL);
         }
         
-        assertSame(bw1, new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build());
+        assertSame(bw1, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
         assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
 
         DefaultObjectWrapper bw3;
         Thread.currentThread().setContextClassLoader(newTCCL);
         try {
-            assertSame(bw2, new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0).build());
+            assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
             
-            DefaultObjectWrapperBuilder bwb = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            DefaultObjectWrapper.Builder bwb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             bwb.setExposeFields(true);
             bw3 = bwb.build();
             assertEquals(3, getDefaultObjectWrapperInstanceCacheSize());
@@ -306,7 +295,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
         
         {
-            DefaultObjectWrapperBuilder bwb = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            DefaultObjectWrapper.Builder bwb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             bwb.setExposeFields(true);
             DefaultObjectWrapper bw4 = bwb.build();
             assertEquals(4, getDefaultObjectWrapperInstanceCacheSize());
@@ -318,19 +307,20 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
     }
     
     public void testClassInrospectorCache() throws TemplateModelException {
-        assertFalse(new DefaultObjectWrapper(Configuration.VERSION_3_0_0).isClassIntrospectionCacheRestricted());
-        assertTrue(new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0)
+        assertFalse(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+                .usePrivateCaches(true).build().isClassIntrospectionCacheRestricted());
+        assertTrue(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
                 .build().isClassIntrospectionCacheRestricted());
         
-        ClassIntrospectorBuilder.clearInstanceCache();
-        DefaultObjectWrapperBuilder.clearInstanceCache();
+        ClassIntrospector.Builder.clearInstanceCache();
+        DefaultObjectWrapper.Builder.clearInstanceCache();
         checkClassIntrospectorCacheSize(0);
         
         List<DefaultObjectWrapper> hardReferences = new LinkedList<>();
-        DefaultObjectWrapperBuilder builder;
+        DefaultObjectWrapper.Builder builder;
 
         {
-            builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             
             DefaultObjectWrapper bw1 = builder.build();
             checkClassIntrospectorCacheSize(1);
@@ -355,7 +345,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
         
         {
-            builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             builder.setExposeFields(true);
             DefaultObjectWrapper ow = builder.build();
             checkClassIntrospectorCacheSize(2);
@@ -434,7 +424,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
         
         {
-            builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             builder.setUseModelCache(true);
             builder.setExposeFields(false);
             builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
@@ -463,7 +453,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
 
         // The ClassInrospector cache couldn't become cleared in reality otherwise:
-        DefaultObjectWrapperBuilder.clearInstanceCache();
+        DefaultObjectWrapper.Builder.clearInstanceCache();
 
         clearClassIntrospectorInstanceCacheReferences(false);
         checkClassIntrospectorCacheSize(8);
@@ -496,7 +486,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
         
         {
-            builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             DefaultObjectWrapper ow = builder.build();
             checkClassIntrospectorCacheSize(8);
             assertEquals(2, getClassIntrospectorNonClearedInstanceCacheSize());
@@ -514,7 +504,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         assertEquals(0, getClassIntrospectorNonClearedInstanceCacheSize());
         
         {
-            builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             builder.setExposeFields(true);
             DefaultObjectWrapper ow = builder.build();
             checkClassIntrospectorCacheSize(1);
@@ -528,7 +518,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
         
         {
-            builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             builder.setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
                 @Override
                 public void process(DecisionInput in, Decision out) {
@@ -549,7 +539,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
         }
 
         {
-            builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+            builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
             builder.setMethodAppearanceFineTuner(
                     GetlessMethodsAsPropertyGettersRule.INSTANCE);  // doesn't spoils sharing
 
@@ -611,14 +601,14 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
     }
     
     static int getClassIntrospectorInstanceCacheSize() {
-        Map instanceCache = ClassIntrospectorBuilder.getInstanceCache();
+        Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
         synchronized (instanceCache) {
             return instanceCache.size();
         }
     }
 
     static int getClassIntrospectorNonClearedInstanceCacheSize() {
-        Map instanceCache = ClassIntrospectorBuilder.getInstanceCache();
+        Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
         synchronized (instanceCache) {
             int cnt = 0;
             for (Iterator it = instanceCache.values().iterator(); it.hasNext(); ) {
@@ -629,7 +619,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
     }
     
     static void clearClassIntrospectorInstanceCacheReferences(boolean enqueue) {
-        Map instanceCache = ClassIntrospectorBuilder.getInstanceCache();
+        Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
         synchronized (instanceCache) {
             for (Iterator it = instanceCache.values().iterator(); it.hasNext(); ) {
                 Reference ref = ((Reference) it.next());
@@ -642,7 +632,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
     }
 
     static int getDefaultObjectWrapperInstanceCacheSize() {
-        Map instanceCache = DefaultObjectWrapperBuilder.getInstanceCache();
+        Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
         synchronized (instanceCache) {
             int size = 0; 
             for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
@@ -653,7 +643,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
     }
 
     static int getDefaultObjectWrapperNonClearedInstanceCacheSize() {
-        Map instanceCache = DefaultObjectWrapperBuilder.getInstanceCache();
+        Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
         synchronized (instanceCache) {
             int cnt = 0;
             for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
@@ -667,7 +657,7 @@ public class DefaultObjectWrapperSingletonsTest extends TestCase {
     }
     
     static void clearDefaultObjectWrapperInstanceCacheReferences(boolean enqueue) {
-        Map instanceCache = DefaultObjectWrapperBuilder.getInstanceCache();
+        Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
         synchronized (instanceCache) {
             for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
                 Map tcclScope = (Map) it1.next();

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dceec32e/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
index 38076a1..93d8a31 100644
--- a/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
+++ b/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
@@ -78,7 +78,7 @@ import com.google.common.collect.ImmutableMap;
 
 public class DefaultObjectWrapperTest {
 
-    private final static DefaultObjectWrapper OW = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0)
+    private final static DefaultObjectWrapper OW = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
             .build();
 
     // This will make sense if we will have multipe incompatibleImprovement versions.
@@ -98,7 +98,7 @@ public class DefaultObjectWrapperTest {
             final Version normalizedVersion = DefaultObjectWrapper.normalizeIncompatibleImprovementsVersion(version);
             actual.add(normalizedVersion);
 
-            final DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(version);
+            final DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(version);
             assertEquals(normalizedVersion, builder.getIncompatibleImprovements());
             assertEquals(normalizedVersion, builder.build().getIncompatibleImprovements());
             
@@ -127,7 +127,7 @@ public class DefaultObjectWrapperTest {
             // expected
         }
         try {
-            new DefaultObjectWrapperBuilder(futureVersion);
+            new DefaultObjectWrapper.Builder(futureVersion);
             fail();
         } catch (IllegalArgumentException e) {
             // expected
@@ -137,17 +137,16 @@ public class DefaultObjectWrapperTest {
     @SuppressWarnings("boxing")
     @Test
     public void testBuilder() throws Exception {
-        DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+        DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
         DefaultObjectWrapper ow = builder.build();
         assertSame(ow, builder.build());
         assertSame(ow.getClass(), DefaultObjectWrapper.class);
         assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
-        assertTrue(ow.isWriteProtected());
     }
 
     @Test
     public void testWrappedTypes() throws Exception {
-        DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_3_0_0);
+        DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
         DefaultObjectWrapper ow = builder.build();
 
         assertThat(ow.wrap(new HashMap()), instanceOf(DefaultMapAdapter.class));
@@ -162,18 +161,13 @@ public class DefaultObjectWrapperTest {
     @Test
     public void testConstructors() throws Exception {
         {
-            DefaultObjectWrapper ow = new DefaultObjectWrapper(Configuration.VERSION_3_0_0);
-            assertEquals(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS, ow.getIncompatibleImprovements());
-        }
-        
-        {
-            DefaultObjectWrapper ow = new DefaultObjectWrapper(Configuration.VERSION_3_0_0);
+            DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+                    .usePrivateCaches(true).build();
             assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
-            assertFalse(ow.isWriteProtected());
         }
         
         try {
-            new DefaultObjectWrapper(new Version(99, 9, 9));
+            new DefaultObjectWrapper.Builder(new Version(99, 9, 9)).build();
             fail();
         } catch (IllegalArgumentException e) {
             assertThat(e.getMessage(), containsString("version"));
@@ -185,8 +179,7 @@ public class DefaultObjectWrapperTest {
     public void testCustomization() throws TemplateModelException {
         CustomizedDefaultObjectWrapper ow = new CustomizedDefaultObjectWrapper(Configuration.VERSION_3_0_0);
         assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
-        assertFalse(ow.isWriteProtected());
-        
+
         TemplateSequenceModel seq = (TemplateSequenceModel) ow.wrap(new Tupple(11, 22));
         assertEquals(2, seq.size());
         assertEquals(11, ow.unwrap(seq.get(0)));
@@ -225,7 +218,7 @@ public class DefaultObjectWrapperTest {
     @SuppressWarnings("boxing")
     @Test
     public void testCompositeValueWrapping() throws TemplateModelException, ClassNotFoundException {
-        DefaultObjectWrapper ow = new DefaultObjectWrapper(Configuration.VERSION_3_0_0);
+        DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
 
         final Map hashMap = new HashMap();
         inintTestMap(hashMap);
@@ -705,20 +698,37 @@ public class DefaultObjectWrapperTest {
 
     @Test
     public void testExposureLevel() throws Exception {
-        final DefaultObjectWrapper ow = new DefaultObjectWrapper(Configuration.VERSION_3_0_0);
-
-        TemplateHashModel tm = (TemplateHashModel) ow.wrap(new TestBean());
-        assertNotNull(tm.get("hashCode"));
-        assertNotNull(tm.get("class"));
-        ow.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
-        assertNull(tm.get("hashCode"));
-        assertNotNull(tm.get("class"));
-        ow.setExposureLevel(DefaultObjectWrapper.EXPOSE_NOTHING);
-        assertNull(tm.get("hashCode"));
-        assertNull(tm.get("class"));
-        ow.setExposureLevel(DefaultObjectWrapper.EXPOSE_ALL);
-        assertNotNull(tm.get("hashCode"));
-        assertNotNull(tm.get("class"));
+        TestBean bean = new TestBean();
+
+        {
+            TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_SAFE);
+            assertNotNull(tm.get("hashCode"));
+            assertNotNull(tm.get("class"));
+        }
+
+        {
+            TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
+            assertNull(tm.get("hashCode"));
+            assertNotNull(tm.get("class"));
+        }
+
+        {
+            TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_NOTHING);
+            assertNull(tm.get("hashCode"));
+            assertNull(tm.get("class"));
+        }
+
+        {
+            TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_ALL);
+            assertNotNull(tm.get("hashCode"));
+            assertNotNull(tm.get("class"));
+        }
+    }
+
+    private TemplateHashModel wrapWithExposureLevel(Object bean, int exposureLevel) throws TemplateModelException {
+        return (TemplateHashModel) new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+                .exposureLevel(exposureLevel).build()
+                .wrap(bean);
     }
 
     private void assertSizeThroughAPIModel(int expectedSize, TemplateModel normalModel) throws TemplateModelException {
@@ -840,7 +850,7 @@ public class DefaultObjectWrapperTest {
     private static class CustomizedDefaultObjectWrapper extends DefaultObjectWrapper {
 
         private CustomizedDefaultObjectWrapper(Version incompatibleImprovements) {
-            super(incompatibleImprovements);
+            super(new DefaultObjectWrapper.Builder(incompatibleImprovements), true);
         }
         
         @Override



Mime
View raw message