diff --git a/src/main/java/freemarker/ext/beans/BeansWrapper.java b/src/main/java/freemarker/ext/beans/BeansWrapper.java
index 953c2f4..d014a69 100644
--- a/src/main/java/freemarker/ext/beans/BeansWrapper.java
+++ b/src/main/java/freemarker/ext/beans/BeansWrapper.java
@@ -96,7 +96,8 @@
     
     /**
      * At this level of exposure, all methods and properties of the
-     * wrapped objects are exposed to the template.
+     * wrapped objects are exposed to the template, and the {@link MemberAccessPolicy}
+     * will be ignored.
      */
     public static final int EXPOSE_ALL = 0;
     
@@ -858,9 +859,6 @@
      */
     protected static Version normalizeIncompatibleImprovementsVersion(Version incompatibleImprovements) {
         _TemplateAPI.checkVersionNotNullAndSupported(incompatibleImprovements);
-        if (incompatibleImprovements.intValue() < _TemplateAPI.VERSION_INT_2_3_0) {
-            throw new IllegalArgumentException("Version must be at least 2.3.0.");
-        }
         return incompatibleImprovements.intValue() >= _TemplateAPI.VERSION_INT_2_3_27 ? Configuration.VERSION_2_3_27
                 : incompatibleImprovements.intValue() == _TemplateAPI.VERSION_INT_2_3_26 ? Configuration.VERSION_2_3_26
                 : is2324Bugfixed(incompatibleImprovements) ? Configuration.VERSION_2_3_24
diff --git a/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java b/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java
index 905bde9..f791d12 100644
--- a/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java
+++ b/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java
@@ -225,10 +225,18 @@
         classIntrospectorBuilder.setExposeFields(exposeFields);
     }
 
+    public MemberAccessPolicy getMemberAccessPolicy() {
+        return classIntrospectorBuilder.getMemberAccessPolicy();
+    }
+
+    public void setMemberAccessPolicy(MemberAccessPolicy memberAccessPolicy) {
+        classIntrospectorBuilder.setMemberAccessPolicy(memberAccessPolicy);
+    }
+
     public boolean getTreatDefaultMethodsAsBeanMembers() {
         return classIntrospectorBuilder.getTreatDefaultMethodsAsBeanMembers();
     }
-    
+
     /** See {@link BeansWrapper#setTreatDefaultMethodsAsBeanMembers(boolean)} */
     public void setTreatDefaultMethodsAsBeanMembers(boolean treatDefaultMethodsAsBeanMembers) {
         classIntrospectorBuilder.setTreatDefaultMethodsAsBeanMembers(treatDefaultMethodsAsBeanMembers);
diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospector.java b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
index c48a91b..72f26cb 100644
--- a/src/main/java/freemarker/ext/beans/ClassIntrospector.java
+++ b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
@@ -53,6 +53,7 @@
 import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput;
 import freemarker.ext.util.ModelCache;
 import freemarker.log.Logger;
+import freemarker.template.Version;
 import freemarker.template.utility.NullArgumentException;
 import freemarker.template.utility.SecurityUtilities;
 
@@ -138,10 +139,11 @@
 
     final int exposureLevel;
     final boolean exposeFields;
+    final MemberAccessPolicy memberAccessPolicy;
     final MethodAppearanceFineTuner methodAppearanceFineTuner;
     final MethodSorter methodSorter;
     final boolean treatDefaultMethodsAsBeanMembers;
-    final boolean bugfixed;
+    final Version incompatibleImprovements;
 
     /** See {@link #getHasSharedInstanceRestrictions()} */
     final private boolean hasSharedInstanceRestrictions;
@@ -178,10 +180,11 @@
 
         this.exposureLevel = builder.getExposureLevel();
         this.exposeFields = builder.getExposeFields();
+        this.memberAccessPolicy = builder.getMemberAccessPolicy();
         this.methodAppearanceFineTuner = builder.getMethodAppearanceFineTuner();
         this.methodSorter = builder.getMethodSorter();
         this.treatDefaultMethodsAsBeanMembers = builder.getTreatDefaultMethodsAsBeanMembers();
-        this.bugfixed = builder.isBugfixed();
+        this.incompatibleImprovements = builder.getIncompatibleImprovements();
 
         this.sharedLock = sharedLock;
 
@@ -264,25 +267,26 @@
      */
     private Map<Object, Object> createClassIntrospectionData(Class<?> clazz) {
         final Map<Object, Object> introspData = new HashMap<Object, Object>();
+        ClassMemberAccessPolicy classMemberAccessPolicy = getClassMemberAccessPolicyIfNotIgnored(clazz);
 
         if (exposeFields) {
-            addFieldsToClassIntrospectionData(introspData, clazz);
+            addFieldsToClassIntrospectionData(introspData, clazz, classMemberAccessPolicy);
         }
 
         final Map<MethodSignature, List<Method>> accessibleMethods = discoverAccessibleMethods(clazz);
 
-        addGenericGetToClassIntrospectionData(introspData, accessibleMethods);
+        addGenericGetToClassIntrospectionData(introspData, accessibleMethods, classMemberAccessPolicy);
 
         if (exposureLevel != BeansWrapper.EXPOSE_NOTHING) {
             try {
-                addBeanInfoToClassIntrospectionData(introspData, clazz, accessibleMethods);
+                addBeanInfoToClassIntrospectionData(introspData, clazz, accessibleMethods, classMemberAccessPolicy);
             } catch (IntrospectionException e) {
                 LOG.warn("Couldn't properly perform introspection for class " + clazz, e);
                 introspData.clear(); // FIXME NBC: Don't drop everything here.
             }
         }
 
-        addConstructorsToClassIntrospectionData(introspData, clazz);
+        addConstructorsToClassIntrospectionData(introspData, clazz, classMemberAccessPolicy);
 
         if (introspData.size() > 1) {
             return introspData;
@@ -294,28 +298,30 @@
         }
     }
 
-    private void addFieldsToClassIntrospectionData(Map<Object, Object> introspData, Class<?> clazz)
-            throws SecurityException {
+    private void addFieldsToClassIntrospectionData(Map<Object, Object> introspData, Class<?> clazz,
+            ClassMemberAccessPolicy classMemberAccessPolicy) throws SecurityException {
         Field[] fields = clazz.getFields();
         for (int i = 0; i < fields.length; i++) {
             Field field = fields[i];
             if ((field.getModifiers() & Modifier.STATIC) == 0) {
-                introspData.put(field.getName(), field);
+                if (classMemberAccessPolicy == null || classMemberAccessPolicy.isFieldExposed(field)) {
+                    introspData.put(field.getName(), field);
+                }
             }
         }
     }
 
     private void addBeanInfoToClassIntrospectionData(
-            Map<Object, Object> introspData, Class<?> clazz, Map<MethodSignature, List<Method>> accessibleMethods)
-            throws IntrospectionException {
+            Map<Object, Object> introspData, Class<?> clazz, Map<MethodSignature, List<Method>> accessibleMethods,
+            ClassMemberAccessPolicy classMemberAccessPolicy) throws IntrospectionException {
         BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
         List<PropertyDescriptor> pdas = getPropertyDescriptors(beanInfo, clazz);
         int pdasLength = pdas.size();
         // Reverse order shouldn't mater, but we keep it to not risk backward incompatibility.
         for (int i = pdasLength - 1; i >= 0; --i) {
             addPropertyDescriptorToClassIntrospectionData(
-                    introspData, pdas.get(i), clazz,
-                    accessibleMethods);
+                    introspData, pdas.get(i),
+                    accessibleMethods, classMemberAccessPolicy);
         }
 
         if (exposureLevel < BeansWrapper.EXPOSE_PROPERTIES_ONLY) {
@@ -327,7 +333,7 @@
             IdentityHashMap<Method, Void> argTypesUsedByIndexerPropReaders = null;
             for (int i = mdsSize - 1; i >= 0; --i) {
                 final Method method = getMatchingAccessibleMethod(mds.get(i).getMethod(), accessibleMethods);
-                if (method != null && isAllowedToExpose(method)) {
+                if (method != null && (isMethodExposed(classMemberAccessPolicy, method))) {
                     decision.setDefaults(method);
                     if (methodAppearanceFineTuner != null) {
                         if (decisionInput == null) {
@@ -344,7 +350,7 @@
                             (decision.getReplaceExistingProperty()
                                     || !(introspData.get(propDesc.getName()) instanceof FastPropertyDescriptor))) {
                         addPropertyDescriptorToClassIntrospectionData(
-                                introspData, propDesc, clazz, accessibleMethods);
+                                introspData, propDesc, accessibleMethods, classMemberAccessPolicy);
                     }
 
                     String methodKey = decision.getExposeMethodAs();
@@ -352,7 +358,8 @@
                         Object previous = introspData.get(methodKey);
                         if (previous instanceof Method) {
                             // Overloaded method - replace Method with a OverloadedMethods
-                            OverloadedMethods overloadedMethods = new OverloadedMethods(bugfixed);
+                            OverloadedMethods overloadedMethods =
+                                    new OverloadedMethods(is2321Bugfixed());
                             overloadedMethods.addMethod((Method) previous);
                             overloadedMethods.addMethod(method);
                             introspData.put(methodKey, overloadedMethods);
@@ -652,9 +659,10 @@
     }
 
     private void addPropertyDescriptorToClassIntrospectionData(Map<Object, Object> introspData,
-            PropertyDescriptor pd, Class<?> clazz, Map<MethodSignature, List<Method>> accessibleMethods) {
+            PropertyDescriptor pd,
+            Map<MethodSignature, List<Method>> accessibleMethods, ClassMemberAccessPolicy classMemberAccessPolicy) {
         Method readMethod = getMatchingAccessibleMethod(pd.getReadMethod(), accessibleMethods);
-        if (readMethod != null && !isAllowedToExpose(readMethod)) {
+        if (readMethod != null && !isMethodExposed(classMemberAccessPolicy, readMethod)) {
             readMethod = null;
         }
         
@@ -662,7 +670,7 @@
         if (pd instanceof IndexedPropertyDescriptor) {
             indexedReadMethod = getMatchingAccessibleMethod(
                     ((IndexedPropertyDescriptor) pd).getIndexedReadMethod(), accessibleMethods);
-            if (indexedReadMethod != null && !isAllowedToExpose(indexedReadMethod)) {
+            if (indexedReadMethod != null && !isMethodExposed(classMemberAccessPolicy, indexedReadMethod)) {
                 indexedReadMethod = null;
             }
             if (indexedReadMethod != null) {
@@ -679,31 +687,42 @@
     }
 
     private void addGenericGetToClassIntrospectionData(Map<Object, Object> introspData,
-            Map<MethodSignature, List<Method>> accessibleMethods) {
+            Map<MethodSignature, List<Method>> accessibleMethods, ClassMemberAccessPolicy classMemberAccessPolicy) {
         Method genericGet = getFirstAccessibleMethod(
                 MethodSignature.GET_STRING_SIGNATURE, accessibleMethods);
         if (genericGet == null) {
             genericGet = getFirstAccessibleMethod(
                     MethodSignature.GET_OBJECT_SIGNATURE, accessibleMethods);
         }
-        if (genericGet != null) {
+        if (genericGet != null && isMethodExposed(classMemberAccessPolicy, genericGet)) {
             introspData.put(GENERIC_GET_KEY, genericGet);
         }
     }
 
     private void addConstructorsToClassIntrospectionData(final Map<Object, Object> introspData,
-            Class<?> clazz) {
+            Class<?> clazz, ClassMemberAccessPolicy classMemberAccessPolicy) {
         try {
-            Constructor<?>[] ctors = clazz.getConstructors();
-            if (ctors.length == 1) {
-                Constructor<?> ctor = ctors[0];
-                introspData.put(CONSTRUCTORS_KEY, new SimpleMethod(ctor, ctor.getParameterTypes()));
-            } else if (ctors.length > 1) {
-                OverloadedMethods overloadedCtors = new OverloadedMethods(bugfixed);
-                for (int i = 0; i < ctors.length; i++) {
-                    overloadedCtors.addConstructor(ctors[i]);
+            Constructor<?>[] ctorsUnfiltered = clazz.getConstructors();
+            List<Constructor<?>> ctors = new ArrayList<Constructor<?>>(ctorsUnfiltered.length);
+            for (Constructor<?> ctor : ctorsUnfiltered) {
+                if (classMemberAccessPolicy == null || classMemberAccessPolicy.isConstructorExposed(ctor)) {
+                    ctors.add(ctor);
                 }
-                introspData.put(CONSTRUCTORS_KEY, overloadedCtors);
+            }
+
+            if (!ctors.isEmpty()) {
+                final Object ctorsIntrospData;
+                if (ctors.size() == 1) {
+                    Constructor<?> ctor = ctors.get(0);
+                    ctorsIntrospData = new SimpleMethod(ctor, ctor.getParameterTypes());
+                } else {
+                    OverloadedMethods overloadedCtors = new OverloadedMethods(is2321Bugfixed());
+                    for (Constructor<?> ctor : ctors) {
+                        overloadedCtors.addConstructor(ctor);
+                    }
+                    ctorsIntrospData = overloadedCtors;
+                }
+                introspData.put(CONSTRUCTORS_KEY, ctorsIntrospData);
             }
         } catch (SecurityException e) {
             LOG.warn("Can't discover constructors for class " + clazz.getName(), e);
@@ -800,8 +819,28 @@
         }
     }
 
-    boolean isAllowedToExpose(Method method) {
-        return exposureLevel < BeansWrapper.EXPOSE_SAFE || !UnsafeMethods.isUnsafeMethod(method);
+    /**
+     * Returns the {@link ClassMemberAccessPolicy}, or {@code null} if it should be ignored because of other settings.
+     * (Ideally, all such rules should be contained in {@link ClassMemberAccessPolicy} alone, but that interface was
+     * added late in history.)
+     *
+     * @see #isMethodExposed(ClassMemberAccessPolicy, Method)
+     */
+    ClassMemberAccessPolicy getClassMemberAccessPolicyIfNotIgnored(Class containingClass) {
+        return exposureLevel < BeansWrapper.EXPOSE_SAFE ? null : memberAccessPolicy.forClass(containingClass);
+    }
+
+    /**
+     * @param classMemberAccessPolicyIfNotIgnored
+     *      The value returned by {@link #getClassMemberAccessPolicyIfNotIgnored(Class)}
+     */
+    static boolean isMethodExposed(ClassMemberAccessPolicy classMemberAccessPolicyIfNotIgnored, Method method) {
+        return classMemberAccessPolicyIfNotIgnored == null
+                || classMemberAccessPolicyIfNotIgnored.isMethodExposed(method);
+    }
+
+    private boolean is2321Bugfixed() {
+        return BeansWrapper.is2321Bugfixed(incompatibleImprovements);
     }
 
     private static Map<Method, Class<?>[]> getArgTypesByMethod(Map<Object, Object> classInfo) {
@@ -1035,7 +1074,11 @@
     boolean getExposeFields() {
         return exposeFields;
     }
-    
+
+    MemberAccessPolicy getMemberAccessPolicy() {
+        return memberAccessPolicy;
+    }
+
     boolean getTreatDefaultMethodsAsBeanMembers() {
         return treatDefaultMethodsAsBeanMembers;
     }
diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java b/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
index 1b54958..1f2d5e0 100644
--- a/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
+++ b/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
@@ -26,21 +26,24 @@
 import java.util.Iterator;
 import java.util.Map;
 
+import freemarker.template.Configuration;
 import freemarker.template.Version;
 import freemarker.template._TemplateAPI;
+import freemarker.template.utility.NullArgumentException;
 
 final class ClassIntrospectorBuilder implements Cloneable {
-    
-    private final boolean bugfixed;
 
     private static final Map<ClassIntrospectorBuilder, Reference<ClassIntrospector>> INSTANCE_CACHE
             = new HashMap<ClassIntrospectorBuilder, Reference<ClassIntrospector>>();
     private static final ReferenceQueue<ClassIntrospector> INSTANCE_CACHE_REF_QUEUE
             = new ReferenceQueue<ClassIntrospector>();
-    
+
+    private final Version incompatibleImprovements;
+
     // Properties and their *defaults*:
     private int exposureLevel = BeansWrapper.EXPOSE_SAFE;
     private boolean exposeFields;
+    private MemberAccessPolicy memberAccessPolicy;
     private boolean treatDefaultMethodsAsBeanMembers;
     private MethodAppearanceFineTuner methodAppearanceFineTuner;
     private MethodSorter methodSorter;
@@ -51,23 +54,33 @@
     // - If you add a new field, review all methods in this class, also the ClassIntrospector constructor
     
     ClassIntrospectorBuilder(ClassIntrospector ci) {
-        bugfixed = ci.bugfixed;
+        incompatibleImprovements = ci.incompatibleImprovements;
         exposureLevel = ci.exposureLevel;
         exposeFields = ci.exposeFields;
+        memberAccessPolicy = ci.memberAccessPolicy;
         treatDefaultMethodsAsBeanMembers = ci.treatDefaultMethodsAsBeanMembers;
         methodAppearanceFineTuner = ci.methodAppearanceFineTuner;
-        methodSorter = ci.methodSorter; 
+        methodSorter = ci.methodSorter;
     }
     
     ClassIntrospectorBuilder(Version incompatibleImprovements) {
         // Warning: incompatibleImprovements must not affect this object at versions increments where there's no
         // change in the BeansWrapper.normalizeIncompatibleImprovements results. That is, this class may don't react
-        // to some version changes that affects BeansWrapper, but not the other way around. 
-        bugfixed = BeansWrapper.is2321Bugfixed(incompatibleImprovements);
+        // to some version changes that affects BeansWrapper, but not the other way around.
+        this.incompatibleImprovements = normalizeIncompatibleImprovementsVersion(incompatibleImprovements);
         treatDefaultMethodsAsBeanMembers
                 = incompatibleImprovements.intValue() >= _TemplateAPI.VERSION_INT_2_3_26;
+        memberAccessPolicy = DefaultMemberAccessPolicy.getInstance(this.incompatibleImprovements);
     }
-    
+
+    private static Version normalizeIncompatibleImprovementsVersion(Version incompatibleImprovements) {
+        _TemplateAPI.checkVersionNotNullAndSupported(incompatibleImprovements);
+        // All breakpoints here must occur in BeansWrapper.normalizeIncompatibleImprovements!
+        return incompatibleImprovements.intValue() >= _TemplateAPI.VERSION_INT_2_3_30 ? Configuration.VERSION_2_3_30
+                : incompatibleImprovements.intValue() >= _TemplateAPI.VERSION_INT_2_3_21 ? Configuration.VERSION_2_3_21
+                : Configuration.VERSION_2_3_0;
+    }
+
     @Override
     protected Object clone() {
         try {
@@ -81,10 +94,11 @@
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + (bugfixed ? 1231 : 1237);
+        result = prime * result + incompatibleImprovements.hashCode();
         result = prime * result + (exposeFields ? 1231 : 1237);
         result = prime * result + (treatDefaultMethodsAsBeanMembers ? 1231 : 1237);
         result = prime * result + exposureLevel;
+        result = prime * result + memberAccessPolicy.hashCode();
         result = prime * result + System.identityHashCode(methodAppearanceFineTuner);
         result = prime * result + System.identityHashCode(methodSorter);
         return result;
@@ -97,10 +111,11 @@
         if (getClass() != obj.getClass()) return false;
         ClassIntrospectorBuilder other = (ClassIntrospectorBuilder) obj;
         
-        if (bugfixed != other.bugfixed) return false;
+        if (!incompatibleImprovements.equals(other.incompatibleImprovements)) return false;
         if (exposeFields != other.exposeFields) return false;
         if (treatDefaultMethodsAsBeanMembers != other.treatDefaultMethodsAsBeanMembers) return false;
         if (exposureLevel != other.exposureLevel) return false;
+        if (!memberAccessPolicy.equals(other.memberAccessPolicy)) return false;
         if (methodAppearanceFineTuner != other.methodAppearanceFineTuner) return false;
         if (methodSorter != other.methodSorter) return false;
         
@@ -137,6 +152,15 @@
         this.treatDefaultMethodsAsBeanMembers = treatDefaultMethodsAsBeanMembers;
     }
 
+    public MemberAccessPolicy getMemberAccessPolicy() {
+        return memberAccessPolicy;
+    }
+
+    public void setMemberAccessPolicy(MemberAccessPolicy memberAccessPolicy) {
+        NullArgumentException.check(memberAccessPolicy);
+        this.memberAccessPolicy = memberAccessPolicy;
+    }
+
     public MethodAppearanceFineTuner getMethodAppearanceFineTuner() {
         return methodAppearanceFineTuner;
     }
@@ -153,6 +177,13 @@
         this.methodSorter = methodSorter;
     }
 
+    /**
+     * Returns the normalized incompatible improvements.
+     */
+    public Version getIncompatibleImprovements() {
+        return incompatibleImprovements;
+    }
+
     private static void removeClearedReferencesFromInstanceCache() {
         Reference<? extends ClassIntrospector> clearedRef;
         while ((clearedRef = INSTANCE_CACHE_REF_QUEUE.poll()) != null) {
@@ -210,8 +241,4 @@
         }
     }
 
-    public boolean isBugfixed() {
-        return bugfixed;
-    }
-    
 }
\ No newline at end of file
diff --git a/src/main/java/freemarker/ext/beans/ClassMemberAccessPolicy.java b/src/main/java/freemarker/ext/beans/ClassMemberAccessPolicy.java
new file mode 100644
index 0000000..3a1e0e6
--- /dev/null
+++ b/src/main/java/freemarker/ext/beans/ClassMemberAccessPolicy.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package freemarker.ext.beans;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * Returned by {@link MemberAccessPolicy#forClass(Class)}. The idea is that {@link MemberAccessPolicy#forClass(Class)}
+ * is called once per class, and then the methods of the resulting {@link ClassMemberAccessPolicy} object will be
+ * called for each member of the class. This can speed up the process as the class-specific lookups will be done only
+ * once per class, not once per member.
+ *
+ * @since 2.3.30
+ */
+public interface ClassMemberAccessPolicy {
+    boolean isMethodExposed(Method method);
+    boolean isConstructorExposed(Constructor<?> constructor);
+    boolean isFieldExposed(Field field);
+}
diff --git a/src/main/java/freemarker/ext/beans/DefaultMemberAccessPolicy.java b/src/main/java/freemarker/ext/beans/DefaultMemberAccessPolicy.java
new file mode 100644
index 0000000..8c1186d
--- /dev/null
+++ b/src/main/java/freemarker/ext/beans/DefaultMemberAccessPolicy.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package freemarker.ext.beans;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import freemarker.template.Version;
+import freemarker.template._TemplateAPI;
+import freemarker.template.utility.ClassUtil;
+
+/**
+ * Legacy black list based member access policy, used only to keep old behavior, as it can't provide meaningful safety.
+ * Do not use it if you allow untrusted users to edit templates!
+ *
+ * @since 2.3.30
+ */
+public final class DefaultMemberAccessPolicy implements MemberAccessPolicy {
+
+    private static final String UNSAFE_METHODS_PROPERTIES = "unsafeMethods.properties";
+    private static final Set<Method> UNSAFE_METHODS = createUnsafeMethodsSet();
+
+    private static Set<Method> createUnsafeMethodsSet() {
+        try {
+            Properties props = ClassUtil.loadProperties(BeansWrapper.class, UNSAFE_METHODS_PROPERTIES);
+            Set<Method> set = new HashSet<Method>(props.size() * 4 / 3, 1f);
+            Map<String, Class<?>> primClasses = createPrimitiveClassesMap();
+            for (Object key : props.keySet()) {
+                try {
+                    set.add(parseMethodSpec((String) key, primClasses));
+                } catch (ClassNotFoundException e) {
+                    if (ClassIntrospector.DEVELOPMENT_MODE) {
+                        throw e;
+                    }
+                } catch (NoSuchMethodException e) {
+                    if (ClassIntrospector.DEVELOPMENT_MODE) {
+                        throw e;
+                    }
+                }
+            }
+            return set;
+        } catch (Exception e) {
+            throw new RuntimeException("Could not load unsafe method set", e);
+        }
+    }
+
+    private static Method parseMethodSpec(String methodSpec, Map<String, Class<?>> primClasses)
+    throws ClassNotFoundException,
+        NoSuchMethodException {
+        int brace = methodSpec.indexOf('(');
+        int dot = methodSpec.lastIndexOf('.', brace);
+        Class<?> clazz = ClassUtil.forName(methodSpec.substring(0, dot));
+        String methodName = methodSpec.substring(dot + 1, brace);
+        String argSpec = methodSpec.substring(brace + 1, methodSpec.length() - 1);
+        StringTokenizer tok = new StringTokenizer(argSpec, ",");
+        int argcount = tok.countTokens();
+        Class<?>[] argTypes = new Class[argcount];
+        for (int i = 0; i < argcount; i++) {
+            String argClassName = tok.nextToken();
+            argTypes[i] = primClasses.get(argClassName);
+            if (argTypes[i] == null) {
+                argTypes[i] = ClassUtil.forName(argClassName);
+            }
+        }
+        return clazz.getMethod(methodName, argTypes);
+    }
+
+    private static Map<String, Class<?>> createPrimitiveClassesMap() {
+        Map<String, Class<?>> map = new HashMap<String, Class<?>>();
+        map.put("boolean", Boolean.TYPE);
+        map.put("byte", Byte.TYPE);
+        map.put("char", Character.TYPE);
+        map.put("short", Short.TYPE);
+        map.put("int", Integer.TYPE);
+        map.put("long", Long.TYPE);
+        map.put("float", Float.TYPE);
+        map.put("double", Double.TYPE);
+        return map;
+    }
+
+    private static final DefaultMemberAccessPolicy INSTANCE = new DefaultMemberAccessPolicy();
+
+    private DefaultMemberAccessPolicy() {
+    }
+
+    /**
+     * Returns the singleton that's compatible with the given incompatible improvements version.
+     */
+    public static DefaultMemberAccessPolicy getInstance(Version incompatibleImprovements) {
+        _TemplateAPI.checkVersionNotNullAndSupported(incompatibleImprovements);
+        // All breakpoints here must occur in ClassIntrospectorBuilder.normalizeIncompatibleImprovementsVersion!
+        // Though currently we don't have any.
+        return INSTANCE;
+    }
+
+    public ClassMemberAccessPolicy forClass(Class<?> containingClass) {
+        return CLASS_MEMBER_ACCESS_POLICY_INSTANCE;
+    }
+
+    private static final BacklistClassMemberAccessPolicy CLASS_MEMBER_ACCESS_POLICY_INSTANCE
+            = new BacklistClassMemberAccessPolicy();
+    private static class BacklistClassMemberAccessPolicy implements ClassMemberAccessPolicy {
+
+        public boolean isMethodExposed(Method method) {
+            return !UNSAFE_METHODS.contains(method);
+        }
+
+        public boolean isConstructorExposed(Constructor<?> constructor) {
+            return true;
+        }
+
+        public boolean isFieldExposed(Field field) {
+            return true;
+        }
+    }
+}
diff --git a/src/main/java/freemarker/ext/beans/MemberAccessPolicy.java b/src/main/java/freemarker/ext/beans/MemberAccessPolicy.java
new file mode 100644
index 0000000..5d72fea
--- /dev/null
+++ b/src/main/java/freemarker/ext/beans/MemberAccessPolicy.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package freemarker.ext.beans;
+
+/**
+ * Implement this to specify what class members are accessible from templates. Implementations must be thread
+ * safe, and instances should be generally singletons on JVM level. The last is because FreeMarker tries to cache
+ * class introspectors in a global (static, JVM-scope) cache for reuse, and that's only possible if the
+ * {@link MemberAccessPolicy} instances used at different places in the JVM are equal according to
+ * {@link #equals(Object) (and the singleton object of course {@link #equals(Object)} with itself).
+ *
+ * @since 2.3.30
+ */
+public interface MemberAccessPolicy {
+    /**
+     * Returns the {@link ClassMemberAccessPolicy} that encapsulates the member access policy for a given class.
+     */
+    ClassMemberAccessPolicy forClass(Class<?> containingClass);
+}
diff --git a/src/main/java/freemarker/ext/beans/StaticModel.java b/src/main/java/freemarker/ext/beans/StaticModel.java
index 28c84bb..1b9e0f5 100644
--- a/src/main/java/freemarker/ext/beans/StaticModel.java
+++ b/src/main/java/freemarker/ext/beans/StaticModel.java
@@ -126,12 +126,14 @@
             }
         }
         if (wrapper.getExposureLevel() < BeansWrapper.EXPOSE_PROPERTIES_ONLY) {
+            ClassMemberAccessPolicy classMemberAccessPolicy =
+                    wrapper.getClassIntrospector().getClassMemberAccessPolicyIfNotIgnored(clazz);
             Method[] methods = clazz.getMethods();
             for (int i = 0; i < methods.length; ++i) {
                 Method method = methods[i];
                 int mod = method.getModifiers();
                 if (Modifier.isPublic(mod) && Modifier.isStatic(mod)
-                        && wrapper.getClassIntrospector().isAllowedToExpose(method)) {
+                        && ClassIntrospector.isMethodExposed(classMemberAccessPolicy, method)) {
                     String name = method.getName();
                     Object obj = map.get(name);
                     if (obj instanceof Method) {
diff --git a/src/main/java/freemarker/ext/beans/UnsafeMethods.java b/src/main/java/freemarker/ext/beans/UnsafeMethods.java
deleted file mode 100644
index 249a6c1..0000000
--- a/src/main/java/freemarker/ext/beans/UnsafeMethods.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.beans;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import freemarker.template.utility.ClassUtil;
-
-class UnsafeMethods {
-
-    private static final String UNSAFE_METHODS_PROPERTIES = "unsafeMethods.properties";
-    private static final Set UNSAFE_METHODS = createUnsafeMethodsSet();
-    
-    private UnsafeMethods() { }
-    
-    static boolean isUnsafeMethod(Method method) {
-        return UNSAFE_METHODS.contains(method);        
-    }
-    
-    private static final Set createUnsafeMethodsSet() {
-        try {
-            Properties props = ClassUtil.loadProperties(BeansWrapper.class, UNSAFE_METHODS_PROPERTIES);
-            Set set = new HashSet(props.size() * 4 / 3, 1f);
-            Map primClasses = createPrimitiveClassesMap();
-            for (Object key : props.keySet()) {
-                try {
-                    set.add(parseMethodSpec((String) key, primClasses));
-                } catch (ClassNotFoundException e) {
-                    if (ClassIntrospector.DEVELOPMENT_MODE) {
-                        throw e;
-                    }
-                } catch (NoSuchMethodException e) {
-                    if (ClassIntrospector.DEVELOPMENT_MODE) {
-                        throw e;
-                    }
-                }
-            }
-            return set;
-        } catch (Exception e) {
-            throw new RuntimeException("Could not load unsafe method set", e);
-        }
-    }
-
-    private static Method parseMethodSpec(String methodSpec, Map primClasses)
-    throws ClassNotFoundException,
-        NoSuchMethodException {
-        int brace = methodSpec.indexOf('(');
-        int dot = methodSpec.lastIndexOf('.', brace);
-        Class clazz = ClassUtil.forName(methodSpec.substring(0, dot));
-        String methodName = methodSpec.substring(dot + 1, brace);
-        String argSpec = methodSpec.substring(brace + 1, methodSpec.length() - 1);
-        StringTokenizer tok = new StringTokenizer(argSpec, ",");
-        int argcount = tok.countTokens();
-        Class[] argTypes = new Class[argcount];
-        for (int i = 0; i < argcount; i++) {
-            String argClassName = tok.nextToken();
-            argTypes[i] = (Class) primClasses.get(argClassName);
-            if (argTypes[i] == null) {
-                argTypes[i] = ClassUtil.forName(argClassName);
-            }
-        }
-        return clazz.getMethod(methodName, argTypes);
-    }
-
-    private static Map createPrimitiveClassesMap() {
-        Map map = new HashMap();
-        map.put("boolean", Boolean.TYPE);
-        map.put("byte", Byte.TYPE);
-        map.put("char", Character.TYPE);
-        map.put("short", Short.TYPE);
-        map.put("int", Integer.TYPE);
-        map.put("long", Long.TYPE);
-        map.put("float", Float.TYPE);
-        map.put("double", Double.TYPE);
-        return map;
-    }
-
-}
diff --git a/src/main/java/freemarker/template/Configuration.java b/src/main/java/freemarker/template/Configuration.java
index c169e9a..3f0031d 100644
--- a/src/main/java/freemarker/template/Configuration.java
+++ b/src/main/java/freemarker/template/Configuration.java
@@ -468,7 +468,10 @@
 
     /** FreeMarker version 2.3.29 (an {@link #Configuration(Version) incompatible improvements break-point}) */
     public static final Version VERSION_2_3_29 = new Version(2, 3, 29);
-    
+
+    /** FreeMarker version 2.3.30 (an {@link #Configuration(Version) incompatible improvements break-point}) */
+    public static final Version VERSION_2_3_30 = new Version(2, 3, 30);
+
     /** The default of {@link #getIncompatibleImprovements()}, currently {@link #VERSION_2_3_0}. */
     public static final Version DEFAULT_INCOMPATIBLE_IMPROVEMENTS = Configuration.VERSION_2_3_0;
     /** @deprecated Use {@link #DEFAULT_INCOMPATIBLE_IMPROVEMENTS} instead. */
diff --git a/src/main/java/freemarker/template/_TemplateAPI.java b/src/main/java/freemarker/template/_TemplateAPI.java
index 30227ca..1b7bb0b 100644
--- a/src/main/java/freemarker/template/_TemplateAPI.java
+++ b/src/main/java/freemarker/template/_TemplateAPI.java
@@ -52,6 +52,7 @@
     public static final int VERSION_INT_2_3_27 = Configuration.VERSION_2_3_27.intValue();
     public static final int VERSION_INT_2_3_28 = Configuration.VERSION_2_3_28.intValue();
     public static final int VERSION_INT_2_3_29 = Configuration.VERSION_2_3_29.intValue();
+    public static final int VERSION_INT_2_3_30 = Configuration.VERSION_2_3_30.intValue();
     public static final int VERSION_INT_2_4_0 = Version.intValueFor(2, 4, 0);
     
     public static void checkVersionNotNullAndSupported(Version incompatibleImprovements) {
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index c8a2aab..4b10a92 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -29187,6 +29187,16 @@
           <itemizedlist>
             <listitem>
               <para>Added
+              <literal>freemarker.ext.beans.MemberAccessPolicy</literal>
+              interface, and the <literal>memberAccessPolicy</literal>
+              property to <literal>BeansWrapper</literal>, and subclasses like
+              <literal>DefaultObjectWrapper</literal>. This allows users to
+              implement their own program logic to decide what members of
+              classes will be exposed to the templates.</para>
+            </listitem>
+
+            <listitem>
+              <para>Added
               <literal>Environment.getDataModelOrSharedVariable(String)</literal>.</para>
             </listitem>
 
diff --git a/src/test/java/freemarker/ext/beans/DefaultObjectWrapperMemberAccessPolicyTest.java b/src/test/java/freemarker/ext/beans/DefaultObjectWrapperMemberAccessPolicyTest.java
new file mode 100644
index 0000000..355a769
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/DefaultObjectWrapperMemberAccessPolicyTest.java
@@ -0,0 +1,409 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package freemarker.ext.beans;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+import freemarker.template.Configuration;
+import freemarker.template.DefaultObjectWrapper;
+import freemarker.template.DefaultObjectWrapperBuilder;
+import freemarker.template.ObjectWrapperAndUnwrapper;
+import freemarker.template.SimpleNumber;
+import freemarker.template.TemplateHashModel;
+import freemarker.template.TemplateMethodModelEx;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
+
+public class DefaultObjectWrapperMemberAccessPolicyTest {
+
+    @Test
+    public void testMethodsWithDefaultMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapper ow = createDefaultMemberAccessPolicyObjectWrapper();
+        TemplateHashModel objM = (TemplateHashModel) ow.wrap(new C());
+
+        assertNotNull(objM.get("m1"));
+        assertEquals("m2(true)", exec(ow, objM.get("m2"), true));
+        assertEquals("staticM()", exec(ow, objM.get("staticM")));
+
+        assertEquals("x", getHashValue(ow, objM, "x"));
+        assertNotNull(objM.get("getX"));
+        assertNotNull(objM.get("setX"));
+
+        assertNull(objM.get("notPublic"));
+
+        assertNull(objM.get("notify"));
+
+        // Because it was overridden, we allow it historically.
+        assertNotNull(objM.get("run"));
+
+        assertEquals("safe wait(1)", exec(ow, objM.get("wait"), 1L));
+        try {
+            exec(ow, objM.get("wait")); // 0 arg overload is not visible, a it's "unsafe"
+            fail();
+        } catch (TemplateModelException e) {
+            assertThat(e.getMessage(), containsString("wait(int)"));
+        }
+    }
+
+    @Test
+    public void testFieldsWithDefaultMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapper ow = createDefaultMemberAccessPolicyObjectWrapper();
+        TemplateHashModel objM = (TemplateHashModel) ow.wrap(new C());
+        assertFieldsNotExposed(objM);
+    }
+
+    private void assertFieldsNotExposed(TemplateHashModel objM) throws TemplateModelException {
+        assertNull(objM.get("publicField1"));
+        assertNull(objM.get("publicField2"));
+        assertNonPublicFieldsNotExposed(objM);
+    }
+
+    private void assertNonPublicFieldsNotExposed(TemplateHashModel objM) throws TemplateModelException {
+        assertNull(objM.get("nonPublicField1"));
+        assertNull(objM.get("nonPublicField2"));
+
+        // Strangely, static fields are banned historically, while static methods aren't.
+        assertNull(objM.get("STATIC_FIELD"));
+    }
+
+    @Test
+    public void testGenericGetWithDefaultMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapper ow = createDefaultMemberAccessPolicyObjectWrapper();
+
+        TemplateHashModel objM = (TemplateHashModel) ow.wrap(new CWithGenericGet());
+
+        assertEquals("get(x)", getHashValue(ow, objM, "x"));
+    }
+
+    @Test
+    public void testConstructorsWithDefaultMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapper ow = createDefaultMemberAccessPolicyObjectWrapper();
+        assertNonPublicConstructorNotExposed(ow);
+
+        assertEquals(CWithConstructor.class, ow.newInstance(CWithConstructor.class, Collections.emptyList())
+                .getClass());
+
+        assertEquals(CWithOverloadedConstructor.class,
+                ow.newInstance(CWithOverloadedConstructor.class, Collections.emptyList())
+                        .getClass());
+
+        assertEquals(CWithOverloadedConstructor.class,
+                ow.newInstance(CWithOverloadedConstructor.class, Collections.singletonList(new SimpleNumber(1)))
+                        .getClass());
+    }
+
+    private void assertNonPublicConstructorNotExposed(DefaultObjectWrapper ow) {
+        try {
+            ow.newInstance(C.class, Collections.emptyList());
+            fail();
+        } catch (TemplateModelException e) {
+            assertThat(e.getMessage(), containsString("constructor"));
+        }
+    }
+
+    @Test
+    public void testExposeAllWithDefaultMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapperBuilder owb = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_30);
+        owb.setExposureLevel(DefaultObjectWrapper.EXPOSE_ALL);
+        DefaultObjectWrapper ow = owb.build();
+        TemplateHashModel objM = (TemplateHashModel) ow.wrap(new C());
+        // Because the MemberAccessPolicy is ignored:
+        assertNotNull(objM.get("notify"));
+        assertFieldsNotExposed(objM);
+    }
+
+    @Test
+    public void testExposeFieldsWithDefaultMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapperBuilder owb = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_30);
+        owb.setExposeFields(true);
+        DefaultObjectWrapper ow = owb.build();
+        {
+            TemplateHashModel objM = (TemplateHashModel) ow.wrap(new C());
+            assertNull(objM.get("notify"));
+            assertEquals(1, getHashValue(ow, objM, "publicField1"));
+            assertEquals(2, getHashValue(ow, objM, "publicField2"));
+            assertNonPublicFieldsNotExposed(objM);
+        }
+
+        {
+            TemplateHashModel objM = (TemplateHashModel) ow.wrap(new CExtended());
+            assertNull(objM.get("notify"));
+            assertEquals(1, getHashValue(ow, objM, "publicField1"));
+            assertEquals(2, getHashValue(ow, objM, "publicField2"));
+            assertEquals(3, getHashValue(ow, objM, "publicField3"));
+            assertNonPublicFieldsNotExposed(objM);
+        }
+    }
+
+    @Test
+    public void testMethodsWithCustomMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapperBuilder owb = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_30);
+        owb.setMemberAccessPolicy(new MemberAccessPolicy() {
+            public ClassMemberAccessPolicy forClass(Class<?> containingClass) {
+                return new ClassMemberAccessPolicy() {
+                    public boolean isMethodExposed(Method method) {
+                        String name = method.getName();
+                        Class<?>[] paramTypes = method.getParameterTypes();
+                        return name.equals("m3")
+                                || (name.equals("m2")
+                                        && (paramTypes.length == 0 || paramTypes[0].equals(boolean.class)));
+                    }
+
+                    public boolean isConstructorExposed(Constructor<?> constructor) {
+                        return true;
+                    }
+
+                    public boolean isFieldExposed(Field field) {
+                        return true;
+                    }
+                };
+            }
+        });
+        DefaultObjectWrapper ow = owb.build();
+
+        TemplateHashModel objM = (TemplateHashModel) ow.wrap(new C());
+        assertNull(objM.get("m1"));
+        assertEquals("m3()", exec(ow, objM.get("m3")));
+        assertEquals("m2()", exec(ow, objM.get("m2")));
+        assertEquals("m2(true)", exec(ow, objM.get("m2"), true));
+        try {
+            exec(ow, objM.get("m2"), 1);
+            fail();
+        } catch (TemplateModelException e) {
+            assertThat(e.getMessage(), containsString("overload"));
+        }
+
+        assertNull(objM.get("notify"));
+   }
+
+    @Test
+    public void testFieldsWithCustomMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapperBuilder owb = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_30);
+        owb.setExposeFields(true);
+        owb.setMemberAccessPolicy(new MemberAccessPolicy() {
+            public ClassMemberAccessPolicy forClass(Class<?> containingClass) {
+                return new ClassMemberAccessPolicy() {
+                    public boolean isMethodExposed(Method method) {
+                        return true;
+                    }
+
+                    public boolean isConstructorExposed(Constructor<?> constructor) {
+                        return true;
+                    }
+
+                    public boolean isFieldExposed(Field field) {
+                        return field.getName().equals("publicField1")
+                                || field.getName().equals("nonPublicField1");
+                    }
+                };
+            }
+        });
+        DefaultObjectWrapper ow = owb.build();
+
+        TemplateHashModel objM = (TemplateHashModel) ow.wrap(new C());
+
+        assertNonPublicFieldsNotExposed(objM);
+        assertEquals(1, getHashValue(ow, objM, "publicField1"));
+        assertNull(getHashValue(ow, objM, "publicField2"));
+    }
+
+    @Test
+    public void testGenericGetWithCustomMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapperBuilder owb = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_30);
+        owb.setMemberAccessPolicy(new MemberAccessPolicy() {
+            public ClassMemberAccessPolicy forClass(Class<?> containingClass) {
+                return new ClassMemberAccessPolicy() {
+                    public boolean isMethodExposed(Method method) {
+                        return false;
+                    }
+
+                    public boolean isConstructorExposed(Constructor<?> constructor) {
+                        return true;
+                    }
+
+                    public boolean isFieldExposed(Field field) {
+                        return true;
+                    }
+                };
+            }
+        });
+        DefaultObjectWrapper ow = owb.build();
+
+        TemplateHashModel objM = (TemplateHashModel) ow.wrap(new CWithGenericGet());
+        assertNull(getHashValue(ow, objM, "x"));
+    }
+
+    @Test
+    public void testConstructorsWithCustomMemberAccessPolicy() throws TemplateModelException {
+        DefaultObjectWrapperBuilder owb = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_30);
+        owb.setMemberAccessPolicy(new MemberAccessPolicy() {
+            public ClassMemberAccessPolicy forClass(Class<?> containingClass) {
+                return new ClassMemberAccessPolicy() {
+                    public boolean isMethodExposed(Method method) {
+                        return true;
+                    }
+
+                    public boolean isConstructorExposed(Constructor<?> constructor) {
+                        return constructor.getDeclaringClass() == CWithOverloadedConstructor.class
+                                && constructor.getParameterTypes().length == 1;
+                    }
+
+                    public boolean isFieldExposed(Field field) {
+                        return true;
+                    }
+                };
+            }
+        });
+        DefaultObjectWrapper ow = owb.build();
+
+        assertNonPublicConstructorNotExposed(ow);
+
+        try {
+            assertEquals(CWithConstructor.class,
+                    ow.newInstance(CWithConstructor.class, Collections.emptyList()).getClass());
+            fail();
+        } catch (TemplateModelException e) {
+            assertThat(e.getMessage(), containsString("constructor"));
+        }
+
+        try {
+            ow.newInstance(CWithOverloadedConstructor.class, Collections.emptyList());
+            fail();
+        } catch (TemplateModelException e) {
+            assertThat(e.getMessage(), containsString("constructor"));
+        }
+
+        assertEquals(CWithOverloadedConstructor.class,
+                ow.newInstance(CWithOverloadedConstructor.class,
+                        Collections.singletonList(new SimpleNumber(1))).getClass());
+    }
+
+    private static DefaultObjectWrapper createDefaultMemberAccessPolicyObjectWrapper() {
+        return new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_30).build();
+    }
+
+    private static Object getHashValue(ObjectWrapperAndUnwrapper ow, TemplateHashModel objM, String key)
+            throws TemplateModelException {
+        return ow.unwrap(objM.get(key));
+    }
+
+    private static Object exec(ObjectWrapperAndUnwrapper ow, TemplateModel objM, Object... args) throws TemplateModelException {
+        assertThat(objM, instanceOf(TemplateMethodModelEx.class));
+        List<TemplateModel> argModels = new ArrayList<TemplateModel>();
+        for (Object arg : args) {
+            argModels.add(ow.wrap(arg));
+        }
+        Object returnValue = ((TemplateMethodModelEx) objM).exec(argModels);
+        return unwrap(ow, returnValue);
+    }
+
+    private static Object unwrap(ObjectWrapperAndUnwrapper ow, Object returnValue) throws TemplateModelException {
+        return returnValue instanceof TemplateModel ? ow.unwrap((TemplateModel) returnValue) : returnValue;
+    }
+
+    public static class C extends Thread {
+        public static final int STATIC_FIELD = 1;
+        public int publicField1 = 1;
+        public int publicField2 = 2;
+        protected int nonPublicField1 = 1;
+        private int nonPublicField2 = 2;
+
+        // Non-public
+        C() {
+
+        }
+
+        void notPublic() {
+        }
+
+        public void m1() {
+        }
+
+        public String m2() {
+            return "m2()";
+        }
+
+        public String m2(int otherOverload) {
+            return "m2(" + otherOverload + ")";
+        }
+
+        public String m2(boolean otherOverload) {
+            return "m2(" + otherOverload + ")";
+        }
+
+        public String m3() {
+            return "m3()";
+        }
+
+        public static String staticM() {
+            return "staticM()";
+        }
+
+        public String getX() {
+            return "x";
+        }
+
+        public void setX(String x) {
+        }
+
+        public String wait(int otherOverload) {
+            return "safe wait(" + otherOverload + ")";
+        }
+
+        @Override
+        public void run() {
+            return;
+        }
+    }
+
+    public static class CExtended extends C {
+        public int publicField3 = 3;
+    }
+
+    public static class CWithGenericGet extends Thread {
+        public String get(String key) {
+            return "get(" + key + ")";
+        }
+    }
+
+    public static class CWithConstructor implements TemplateModel {
+        public CWithConstructor() {
+        }
+    }
+
+    public static class CWithOverloadedConstructor implements TemplateModel {
+        public CWithOverloadedConstructor() {
+        }
+
+        public CWithOverloadedConstructor(int x) {
+        }
+    }
+
+}
