diff --git a/src/main/java/org/apache/commons/beanutils2/MappedPropertyDescriptor.java b/src/main/java/org/apache/commons/beanutils2/MappedPropertyDescriptor.java
index a798409..7248794 100644
--- a/src/main/java/org/apache/commons/beanutils2/MappedPropertyDescriptor.java
+++ b/src/main/java/org/apache/commons/beanutils2/MappedPropertyDescriptor.java
@@ -1,529 +1,529 @@
-/*
- * 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.commons.beanutils2;
-
-
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-
-/**
- * A MappedPropertyDescriptor describes one mapped property.
- * Mapped properties are multivalued properties like indexed properties
- * but that are accessed with a String key instead of an index.
- * Such property values are typically stored in a Map collection.
- * For this class to work properly, a mapped value must have
- * getter and setter methods of the form
- * <p><code>get<strong>Property</strong>(String key)</code> and
- * <p><code>set<strong>Property</strong>(String key, Object value)</code>,
- * <p>where <code><strong>Property</strong></code> must be replaced
- * by the name of the property.
- * @see java.beans.PropertyDescriptor
- *
- */
-public class MappedPropertyDescriptor extends PropertyDescriptor {
-    // ----------------------------------------------------- Instance Variables
-
-    /**
-     * The underlying data type of the property we are describing.
-     */
-    private Reference<Class<?>> mappedPropertyTypeRef;
-
-    /**
-     * The reader method for this property (if any).
-     */
-    private MappedMethodReference mappedReadMethodRef;
-
-    /**
-     * The writer method for this property (if any).
-     */
-    private MappedMethodReference mappedWriteMethodRef;
-
-    /**
-     * The parameter types array for the reader method signature.
-     */
-    private static final Class<?>[] STRING_CLASS_PARAMETER = new Class[]{String.class};
-
-    // ----------------------------------------------------------- Constructors
-
-    /**
-     * Constructs a MappedPropertyDescriptor for a property that follows
-     * the standard Java convention by having getFoo and setFoo
-     * accessor methods, with the addition of a String parameter (the key).
-     * Thus if the argument name is "fred", it will
-     * assume that the writer method is "setFred" and the reader method
-     * is "getFred".  Note that the property name should start with a lower
-     * case character, which will be capitalized in the method names.
-     *
-     * @param propertyName The programmatic name of the property.
-     * @param beanClass The Class object for the target bean.  For
-     *        example sun.beans.OurButton.class.
-     *
-     * @throws IntrospectionException if an exception occurs during
-     *              introspection.
-     */
-    public MappedPropertyDescriptor(final String propertyName, final Class<?> beanClass)
-            throws IntrospectionException {
-
-        super(propertyName, null, null);
-
-        if (propertyName == null || propertyName.length() == 0) {
-            throw new IntrospectionException("bad property name: " +
-                    propertyName + " on class: " + beanClass.getClass().getName());
-        }
-
-        setName(propertyName);
-        final String base = capitalizePropertyName(propertyName);
-
-        // Look for mapped read method and matching write method
-        Method mappedReadMethod = null;
-        Method mappedWriteMethod = null;
-        try {
-            try {
-                mappedReadMethod = getMethod(beanClass, "get" + base,
-                        STRING_CLASS_PARAMETER);
-            } catch (final IntrospectionException e) {
-                mappedReadMethod = getMethod(beanClass, "is" + base,
-                        STRING_CLASS_PARAMETER);
-            }
-            final Class<?>[] params = { String.class, mappedReadMethod.getReturnType() };
-            mappedWriteMethod = getMethod(beanClass, "set" + base, params);
-        } catch (final IntrospectionException e) {
-            /* Swallow IntrospectionException
-             * TODO: Why?
-             */
-        }
-
-        // If there's no read method, then look for just a write method
-        if (mappedReadMethod == null) {
-            mappedWriteMethod = getMethod(beanClass, "set" + base, 2);
-        }
-
-        if (mappedReadMethod == null && mappedWriteMethod == null) {
-            throw new IntrospectionException("Property '" + propertyName +
-                    "' not found on " +
-                    beanClass.getName());
-        }
-        mappedReadMethodRef  = new MappedMethodReference(mappedReadMethod);
-        mappedWriteMethodRef = new MappedMethodReference(mappedWriteMethod);
-
-        findMappedPropertyType();
-    }
-
-
-    /**
-     * This constructor takes the name of a mapped property, and method
-     * names for reading and writing the property.
-     *
-     * @param propertyName The programmatic name of the property.
-     * @param beanClass The Class object for the target bean.  For
-     *        example sun.beans.OurButton.class.
-     * @param mappedGetterName The name of the method used for
-     *          reading one of the property values.  May be null if the
-     *          property is write-only.
-     * @param mappedSetterName The name of the method used for writing
-     *          one of the property values.  May be null if the property is
-     *          read-only.
-     *
-     * @throws IntrospectionException if an exception occurs during
-     *              introspection.
-     */
-    public MappedPropertyDescriptor(final String propertyName, final Class<?> beanClass,
-                                    final String mappedGetterName, final String mappedSetterName)
-            throws IntrospectionException {
-
-        super(propertyName, null, null);
-
-        if (propertyName == null || propertyName.length() == 0) {
-            throw new IntrospectionException("bad property name: " +
-                    propertyName);
-        }
-        setName(propertyName);
-
-        // search the mapped get and set methods
-        Method mappedReadMethod = null;
-        Method mappedWriteMethod = null;
-        mappedReadMethod =
-            getMethod(beanClass, mappedGetterName, STRING_CLASS_PARAMETER);
-
-        if (mappedReadMethod != null) {
-            final Class<?>[] params = { String.class, mappedReadMethod.getReturnType() };
-            mappedWriteMethod =
-                getMethod(beanClass, mappedSetterName, params);
-        } else {
-            mappedWriteMethod =
-                getMethod(beanClass, mappedSetterName, 2);
-        }
-        mappedReadMethodRef  = new MappedMethodReference(mappedReadMethod);
-        mappedWriteMethodRef = new MappedMethodReference(mappedWriteMethod);
-
-        findMappedPropertyType();
-    }
-
-    /**
-     * This constructor takes the name of a mapped property, and Method
-     * objects for reading and writing the property.
-     *
-     * @param propertyName The programmatic name of the property.
-     * @param mappedGetter The method used for reading one of
-     *          the property values.  May be be null if the property
-     *          is write-only.
-     * @param mappedSetter The method used for writing one the
-     *          property values.  May be null if the property is read-only.
-     *
-     * @throws IntrospectionException if an exception occurs during
-     *              introspection.
-     */
-    public MappedPropertyDescriptor(final String propertyName,
-                                    final Method mappedGetter, final Method mappedSetter)
-            throws IntrospectionException {
-
-        super(propertyName, mappedGetter, mappedSetter);
-
-        if (propertyName == null || propertyName.length() == 0) {
-            throw new IntrospectionException("bad property name: " +
-                    propertyName);
-        }
-
-        setName(propertyName);
-        mappedReadMethodRef  = new MappedMethodReference(mappedGetter);
-        mappedWriteMethodRef = new MappedMethodReference(mappedSetter);
-        findMappedPropertyType();
-    }
-
-    // -------------------------------------------------------- Public Methods
-
-    /**
-     * Gets the Class object for the property values.
-     *
-     * @return The Java type info for the property values.  Note that
-     * the "Class" object may describe a built-in Java type such as "int".
-     * The result may be "null" if this is a mapped property that
-     * does not support non-keyed access.
-     * <p>
-     * This is the type that will be returned by the mappedReadMethod.
-     */
-    public Class<?> getMappedPropertyType() {
-        return mappedPropertyTypeRef.get();
-    }
-
-    /**
-     * Gets the method that should be used to read one of the property value.
-     *
-     * @return The method that should be used to read the property value.
-     * May return null if the property can't be read.
-     */
-    public Method getMappedReadMethod() {
-        return mappedReadMethodRef.get();
-    }
-
-    /**
-     * Sets the method that should be used to read one of the property value.
-     *
-     * @param mappedGetter The mapped getter method.
-     * @throws IntrospectionException If an error occurs finding the
-     * mapped property
-     */
-    public void setMappedReadMethod(final Method mappedGetter)
-            throws IntrospectionException {
-        mappedReadMethodRef = new MappedMethodReference(mappedGetter);
-        findMappedPropertyType();
-    }
-
-    /**
-     * Gets the method that should be used to write one of the property value.
-     *
-     * @return The method that should be used to write one of the property value.
-     * May return null if the property can't be written.
-     */
-    public Method getMappedWriteMethod() {
-        return mappedWriteMethodRef.get();
-    }
-
-    /**
-     * Sets the method that should be used to write the property value.
-     *
-     * @param mappedSetter The mapped setter method.
-     * @throws IntrospectionException If an error occurs finding the
-     * mapped property
-     */
-    public void setMappedWriteMethod(final Method mappedSetter)
-            throws IntrospectionException {
-        mappedWriteMethodRef = new MappedMethodReference(mappedSetter);
-        findMappedPropertyType();
-    }
-
-    // ------------------------------------------------------- Private Methods
-
-    /**
-     * Introspect our bean class to identify the corresponding getter
-     * and setter methods.
-     */
-    private void findMappedPropertyType() throws IntrospectionException {
-        try {
-            final Method mappedReadMethod  = getMappedReadMethod();
-            final Method mappedWriteMethod = getMappedWriteMethod();
-            Class<?> mappedPropertyType = null;
-            if (mappedReadMethod != null) {
-                if (mappedReadMethod.getParameterTypes().length != 1) {
-                    throw new IntrospectionException
-                            ("bad mapped read method arg count");
-                }
-                mappedPropertyType = mappedReadMethod.getReturnType();
-                if (mappedPropertyType == Void.TYPE) {
-                    throw new IntrospectionException
-                            ("mapped read method " +
-                            mappedReadMethod.getName() + " returns void");
-                }
-            }
-
-            if (mappedWriteMethod != null) {
-                final Class<?>[] params = mappedWriteMethod.getParameterTypes();
-                if (params.length != 2) {
-                    throw new IntrospectionException
-                            ("bad mapped write method arg count");
-                }
-                if (mappedPropertyType != null &&
-                        mappedPropertyType != params[1]) {
-                    throw new IntrospectionException
-                            ("type mismatch between mapped read and write methods");
-                }
-                mappedPropertyType = params[1];
-            }
-            mappedPropertyTypeRef = new SoftReference<Class<?>>(mappedPropertyType);
-        } catch (final IntrospectionException ex) {
-            throw ex;
-        }
-    }
-
-
-    /**
-     * Return a capitalized version of the specified property name.
-     *
-     * @param s The property name
-     */
-    private static String capitalizePropertyName(final String s) {
-        if (s.length() == 0) {
-            return s;
-        }
-
-        final char[] chars = s.toCharArray();
-        chars[0] = Character.toUpperCase(chars[0]);
-        return new String(chars);
-    }
-
-    /**
-     * Find a method on a class with a specified number of parameters.
-     */
-    private static Method internalGetMethod(final Class<?> initial, final String methodName,
-                                            final int parameterCount) {
-        // For overridden methods we need to find the most derived version.
-        // So we start with the given class and walk up the superclass chain.
-        for (Class<?> clazz = initial; clazz != null; clazz = clazz.getSuperclass()) {
-            final Method[] methods = clazz.getDeclaredMethods();
-            for (final Method method : methods) {
-                if (method == null) {
-                    continue;
-                }
-                // skip static methods.
-                final int mods = method.getModifiers();
-                if (!Modifier.isPublic(mods) ||
-                    Modifier.isStatic(mods)) {
-                    continue;
-                }
-                if (method.getName().equals(methodName) &&
-                        method.getParameterTypes().length == parameterCount) {
-                    return method;
-                }
-            }
-        }
-
-        // Now check any inherited interfaces.  This is necessary both when
-        // the argument class is itself an interface, and when the argument
-        // class is an abstract class.
-        final Class<?>[] interfaces = initial.getInterfaces();
-        for (final Class<?> interface1 : interfaces) {
-            final Method method = internalGetMethod(interface1, methodName, parameterCount);
-            if (method != null) {
-                return method;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Find a method on a class with a specified number of parameters.
-     */
-    private static Method getMethod(final Class<?> clazz, final String methodName, final int parameterCount)
-            throws IntrospectionException {
-        if (methodName == null) {
-            return null;
-        }
-
-        final Method method = internalGetMethod(clazz, methodName, parameterCount);
-        if (method != null) {
-            return method;
-        }
-
-        // No Method found
-        throw new IntrospectionException("No method \"" + methodName +
-                "\" with " + parameterCount + " parameter(s)");
-    }
-
-    /**
-     * Find a method on a class with a specified parameter list.
-     */
-    private static Method getMethod(final Class<?> clazz, final String methodName, final Class<?>[] parameterTypes)
-                                           throws IntrospectionException {
-        if (methodName == null) {
-            return null;
-        }
-
-        final Method method = MethodUtils.getMatchingAccessibleMethod(clazz, methodName, parameterTypes);
-        if (method != null) {
-            return method;
-        }
-
-        final int parameterCount = parameterTypes == null ? 0 : parameterTypes.length;
-
-        // No Method found
-        throw new IntrospectionException("No method \"" + methodName +
-                "\" with " + parameterCount + " parameter(s) of matching types.");
-    }
-
-    /**
-     * Holds a {@link Method} in a {@link SoftReference} so that it
-     * it doesn't prevent any ClassLoader being garbage collected, but
-     * tries to re-create the method if the method reference has been
-     * released.
-     *
-     * See https://issues.apache.org/jira/browse/BEANUTILS-291
-     */
-    private static class MappedMethodReference {
-        private String className;
-        private String methodName;
-        private Reference<Method> methodRef;
-        private Reference<Class<?>> classRef;
-        private Reference<Class<?>> writeParamTypeRef0;
-        private Reference<Class<?>> writeParamTypeRef1;
-        private String[] writeParamClassNames;
-        MappedMethodReference(final Method m) {
-            if (m != null) {
-                className = m.getDeclaringClass().getName();
-                methodName = m.getName();
-                methodRef = new SoftReference<>(m);
-                classRef = new WeakReference<Class<?>>(m.getDeclaringClass());
-                final Class<?>[] types = m.getParameterTypes();
-                if (types.length == 2) {
-                    writeParamTypeRef0 = new WeakReference<Class<?>>(types[0]);
-                    writeParamTypeRef1 = new WeakReference<Class<?>>(types[1]);
-                    writeParamClassNames = new String[2];
-                    writeParamClassNames[0] = types[0].getName();
-                    writeParamClassNames[1] = types[1].getName();
-                }
-            }
-        }
-        private Method get() {
-            if (methodRef == null) {
-                return null;
-            }
-            Method m = methodRef.get();
-            if (m == null) {
-                Class<?> clazz = classRef.get();
-                if (clazz == null) {
-                    clazz = reLoadClass();
-                    if (clazz != null) {
-                        classRef = new WeakReference<Class<?>>(clazz);
-                    }
-                }
-                if (clazz == null) {
-                    throw new RuntimeException("Method " + methodName + " for " +
-                            className + " could not be reconstructed - class reference has gone");
-                }
-                Class<?>[] paramTypes = null;
-                if (writeParamClassNames != null) {
-                    paramTypes = new Class[2];
-                    paramTypes[0] = writeParamTypeRef0.get();
-                    if (paramTypes[0] == null) {
-                        paramTypes[0] = reLoadClass(writeParamClassNames[0]);
-                        if (paramTypes[0] != null) {
-                            writeParamTypeRef0 = new WeakReference<Class<?>>(paramTypes[0]);
-                        }
-                    }
-                    paramTypes[1] = writeParamTypeRef1.get();
-                    if (paramTypes[1] == null) {
-                        paramTypes[1] = reLoadClass(writeParamClassNames[1]);
-                        if (paramTypes[1] != null) {
-                            writeParamTypeRef1 = new WeakReference<Class<?>>(paramTypes[1]);
-                        }
-                    }
-                } else {
-                    paramTypes = STRING_CLASS_PARAMETER;
-                }
-                try {
-                    m = clazz.getMethod(methodName, paramTypes);
-                    // Un-comment following line for testing
-                    // System.out.println("Recreated Method " + methodName + " for " + className);
-                } catch (final NoSuchMethodException e) {
-                    throw new RuntimeException("Method " + methodName + " for " +
-                            className + " could not be reconstructed - method not found");
-                }
-                methodRef = new SoftReference<>(m);
-            }
-            return m;
-        }
-
-        /**
-         * Try to re-load the class
-         */
-        private Class<?> reLoadClass() {
-            return reLoadClass(className);
-        }
-
-        /**
-         * Try to re-load the class
-         */
-        private Class<?> reLoadClass(final String name) {
-
-            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
-            // Try the context class loader
-            if (classLoader != null) {
-                try {
-                    return classLoader.loadClass(name);
-                } catch (final ClassNotFoundException e) {
-                    // ignore
-                }
-            }
-
-            // Try this class's class loader
-            classLoader = MappedPropertyDescriptor.class.getClassLoader();
-            try {
-                return classLoader.loadClass(name);
-            } catch (final ClassNotFoundException e) {
-                return null;
-            }
-        }
-    }
-}
+/*
+ * 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.commons.beanutils2;
+
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+
+/**
+ * A MappedPropertyDescriptor describes one mapped property.
+ * Mapped properties are multivalued properties like indexed properties
+ * but that are accessed with a String key instead of an index.
+ * Such property values are typically stored in a Map collection.
+ * For this class to work properly, a mapped value must have
+ * getter and setter methods of the form
+ * <p><code>get<strong>Property</strong>(String key)</code> and
+ * <p><code>set<strong>Property</strong>(String key, Object value)</code>,
+ * <p>where <code><strong>Property</strong></code> must be replaced
+ * by the name of the property.
+ * @see java.beans.PropertyDescriptor
+ *
+ */
+public class MappedPropertyDescriptor extends PropertyDescriptor {
+    // ----------------------------------------------------- Instance Variables
+
+    /**
+     * The underlying data type of the property we are describing.
+     */
+    private Reference<Class<?>> mappedPropertyTypeRef;
+
+    /**
+     * The reader method for this property (if any).
+     */
+    private MappedMethodReference mappedReadMethodRef;
+
+    /**
+     * The writer method for this property (if any).
+     */
+    private MappedMethodReference mappedWriteMethodRef;
+
+    /**
+     * The parameter types array for the reader method signature.
+     */
+    private static final Class<?>[] STRING_CLASS_PARAMETER = new Class[]{String.class};
+
+    // ----------------------------------------------------------- Constructors
+
+    /**
+     * Constructs a MappedPropertyDescriptor for a property that follows
+     * the standard Java convention by having getFoo and setFoo
+     * accessor methods, with the addition of a String parameter (the key).
+     * Thus if the argument name is "fred", it will
+     * assume that the writer method is "setFred" and the reader method
+     * is "getFred".  Note that the property name should start with a lower
+     * case character, which will be capitalized in the method names.
+     *
+     * @param propertyName The programmatic name of the property.
+     * @param beanClass The Class object for the target bean.  For
+     *        example sun.beans.OurButton.class.
+     *
+     * @throws IntrospectionException if an exception occurs during
+     *              introspection.
+     */
+    public MappedPropertyDescriptor(final String propertyName, final Class<?> beanClass)
+            throws IntrospectionException {
+
+        super(propertyName, null, null);
+
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException("bad property name: " +
+                    propertyName + " on class: " + beanClass.getClass().getName());
+        }
+
+        setName(propertyName);
+        final String base = capitalizePropertyName(propertyName);
+
+        // Look for mapped read method and matching write method
+        Method mappedReadMethod = null;
+        Method mappedWriteMethod = null;
+        try {
+            try {
+                mappedReadMethod = getMethod(beanClass, "get" + base,
+                        STRING_CLASS_PARAMETER);
+            } catch (final IntrospectionException e) {
+                mappedReadMethod = getMethod(beanClass, "is" + base,
+                        STRING_CLASS_PARAMETER);
+            }
+            final Class<?>[] params = { String.class, mappedReadMethod.getReturnType() };
+            mappedWriteMethod = getMethod(beanClass, "set" + base, params);
+        } catch (final IntrospectionException e) {
+            /* Swallow IntrospectionException
+             * TODO: Why?
+             */
+        }
+
+        // If there's no read method, then look for just a write method
+        if (mappedReadMethod == null) {
+            mappedWriteMethod = getMethod(beanClass, "set" + base, 2);
+        }
+
+        if (mappedReadMethod == null && mappedWriteMethod == null) {
+            throw new IntrospectionException("Property '" + propertyName +
+                    "' not found on " +
+                    beanClass.getName());
+        }
+        mappedReadMethodRef  = new MappedMethodReference(mappedReadMethod);
+        mappedWriteMethodRef = new MappedMethodReference(mappedWriteMethod);
+
+        findMappedPropertyType();
+    }
+
+
+    /**
+     * This constructor takes the name of a mapped property, and method
+     * names for reading and writing the property.
+     *
+     * @param propertyName The programmatic name of the property.
+     * @param beanClass The Class object for the target bean.  For
+     *        example sun.beans.OurButton.class.
+     * @param mappedGetterName The name of the method used for
+     *          reading one of the property values.  May be null if the
+     *          property is write-only.
+     * @param mappedSetterName The name of the method used for writing
+     *          one of the property values.  May be null if the property is
+     *          read-only.
+     *
+     * @throws IntrospectionException if an exception occurs during
+     *              introspection.
+     */
+    public MappedPropertyDescriptor(final String propertyName, final Class<?> beanClass,
+                                    final String mappedGetterName, final String mappedSetterName)
+            throws IntrospectionException {
+
+        super(propertyName, null, null);
+
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException("bad property name: " +
+                    propertyName);
+        }
+        setName(propertyName);
+
+        // search the mapped get and set methods
+        Method mappedReadMethod = null;
+        Method mappedWriteMethod = null;
+        mappedReadMethod =
+            getMethod(beanClass, mappedGetterName, STRING_CLASS_PARAMETER);
+
+        if (mappedReadMethod != null) {
+            final Class<?>[] params = { String.class, mappedReadMethod.getReturnType() };
+            mappedWriteMethod =
+                getMethod(beanClass, mappedSetterName, params);
+        } else {
+            mappedWriteMethod =
+                getMethod(beanClass, mappedSetterName, 2);
+        }
+        mappedReadMethodRef  = new MappedMethodReference(mappedReadMethod);
+        mappedWriteMethodRef = new MappedMethodReference(mappedWriteMethod);
+
+        findMappedPropertyType();
+    }
+
+    /**
+     * This constructor takes the name of a mapped property, and Method
+     * objects for reading and writing the property.
+     *
+     * @param propertyName The programmatic name of the property.
+     * @param mappedGetter The method used for reading one of
+     *          the property values.  May be be null if the property
+     *          is write-only.
+     * @param mappedSetter The method used for writing one the
+     *          property values.  May be null if the property is read-only.
+     *
+     * @throws IntrospectionException if an exception occurs during
+     *              introspection.
+     */
+    public MappedPropertyDescriptor(final String propertyName,
+                                    final Method mappedGetter, final Method mappedSetter)
+            throws IntrospectionException {
+
+        super(propertyName, mappedGetter, mappedSetter);
+
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException("bad property name: " +
+                    propertyName);
+        }
+
+        setName(propertyName);
+        mappedReadMethodRef  = new MappedMethodReference(mappedGetter);
+        mappedWriteMethodRef = new MappedMethodReference(mappedSetter);
+        findMappedPropertyType();
+    }
+
+    // -------------------------------------------------------- Public Methods
+
+    /**
+     * Gets the Class object for the property values.
+     *
+     * @return The Java type info for the property values.  Note that
+     * the "Class" object may describe a built-in Java type such as "int".
+     * The result may be "null" if this is a mapped property that
+     * does not support non-keyed access.
+     * <p>
+     * This is the type that will be returned by the mappedReadMethod.
+     */
+    public Class<?> getMappedPropertyType() {
+        return mappedPropertyTypeRef.get();
+    }
+
+    /**
+     * Gets the method that should be used to read one of the property value.
+     *
+     * @return The method that should be used to read the property value.
+     * May return null if the property can't be read.
+     */
+    public Method getMappedReadMethod() {
+        return mappedReadMethodRef.get();
+    }
+
+    /**
+     * Sets the method that should be used to read one of the property value.
+     *
+     * @param mappedGetter The mapped getter method.
+     * @throws IntrospectionException If an error occurs finding the
+     * mapped property
+     */
+    public void setMappedReadMethod(final Method mappedGetter)
+            throws IntrospectionException {
+        mappedReadMethodRef = new MappedMethodReference(mappedGetter);
+        findMappedPropertyType();
+    }
+
+    /**
+     * Gets the method that should be used to write one of the property value.
+     *
+     * @return The method that should be used to write one of the property value.
+     * May return null if the property can't be written.
+     */
+    public Method getMappedWriteMethod() {
+        return mappedWriteMethodRef.get();
+    }
+
+    /**
+     * Sets the method that should be used to write the property value.
+     *
+     * @param mappedSetter The mapped setter method.
+     * @throws IntrospectionException If an error occurs finding the
+     * mapped property
+     */
+    public void setMappedWriteMethod(final Method mappedSetter)
+            throws IntrospectionException {
+        mappedWriteMethodRef = new MappedMethodReference(mappedSetter);
+        findMappedPropertyType();
+    }
+
+    // ------------------------------------------------------- Private Methods
+
+    /**
+     * Introspect our bean class to identify the corresponding getter
+     * and setter methods.
+     */
+    private void findMappedPropertyType() throws IntrospectionException {
+        try {
+            final Method mappedReadMethod  = getMappedReadMethod();
+            final Method mappedWriteMethod = getMappedWriteMethod();
+            Class<?> mappedPropertyType = null;
+            if (mappedReadMethod != null) {
+                if (mappedReadMethod.getParameterTypes().length != 1) {
+                    throw new IntrospectionException
+                            ("bad mapped read method arg count");
+                }
+                mappedPropertyType = mappedReadMethod.getReturnType();
+                if (mappedPropertyType == Void.TYPE) {
+                    throw new IntrospectionException
+                            ("mapped read method " +
+                            mappedReadMethod.getName() + " returns void");
+                }
+            }
+
+            if (mappedWriteMethod != null) {
+                final Class<?>[] params = mappedWriteMethod.getParameterTypes();
+                if (params.length != 2) {
+                    throw new IntrospectionException
+                            ("bad mapped write method arg count");
+                }
+                if (mappedPropertyType != null &&
+                        mappedPropertyType != params[1]) {
+                    throw new IntrospectionException
+                            ("type mismatch between mapped read and write methods");
+                }
+                mappedPropertyType = params[1];
+            }
+            mappedPropertyTypeRef = new SoftReference<>(mappedPropertyType);
+        } catch (final IntrospectionException ex) {
+            throw ex;
+        }
+    }
+
+
+    /**
+     * Return a capitalized version of the specified property name.
+     *
+     * @param s The property name
+     */
+    private static String capitalizePropertyName(final String s) {
+        if (s.length() == 0) {
+            return s;
+        }
+
+        final char[] chars = s.toCharArray();
+        chars[0] = Character.toUpperCase(chars[0]);
+        return new String(chars);
+    }
+
+    /**
+     * Find a method on a class with a specified number of parameters.
+     */
+    private static Method internalGetMethod(final Class<?> initial, final String methodName,
+                                            final int parameterCount) {
+        // For overridden methods we need to find the most derived version.
+        // So we start with the given class and walk up the superclass chain.
+        for (Class<?> clazz = initial; clazz != null; clazz = clazz.getSuperclass()) {
+            final Method[] methods = clazz.getDeclaredMethods();
+            for (final Method method : methods) {
+                if (method == null) {
+                    continue;
+                }
+                // skip static methods.
+                final int mods = method.getModifiers();
+                if (!Modifier.isPublic(mods) ||
+                    Modifier.isStatic(mods)) {
+                    continue;
+                }
+                if (method.getName().equals(methodName) &&
+                        method.getParameterTypes().length == parameterCount) {
+                    return method;
+                }
+            }
+        }
+
+        // Now check any inherited interfaces.  This is necessary both when
+        // the argument class is itself an interface, and when the argument
+        // class is an abstract class.
+        final Class<?>[] interfaces = initial.getInterfaces();
+        for (final Class<?> interface1 : interfaces) {
+            final Method method = internalGetMethod(interface1, methodName, parameterCount);
+            if (method != null) {
+                return method;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Find a method on a class with a specified number of parameters.
+     */
+    private static Method getMethod(final Class<?> clazz, final String methodName, final int parameterCount)
+            throws IntrospectionException {
+        if (methodName == null) {
+            return null;
+        }
+
+        final Method method = internalGetMethod(clazz, methodName, parameterCount);
+        if (method != null) {
+            return method;
+        }
+
+        // No Method found
+        throw new IntrospectionException("No method \"" + methodName +
+                "\" with " + parameterCount + " parameter(s)");
+    }
+
+    /**
+     * Find a method on a class with a specified parameter list.
+     */
+    private static Method getMethod(final Class<?> clazz, final String methodName, final Class<?>[] parameterTypes)
+                                           throws IntrospectionException {
+        if (methodName == null) {
+            return null;
+        }
+
+        final Method method = MethodUtils.getMatchingAccessibleMethod(clazz, methodName, parameterTypes);
+        if (method != null) {
+            return method;
+        }
+
+        final int parameterCount = parameterTypes == null ? 0 : parameterTypes.length;
+
+        // No Method found
+        throw new IntrospectionException("No method \"" + methodName +
+                "\" with " + parameterCount + " parameter(s) of matching types.");
+    }
+
+    /**
+     * Holds a {@link Method} in a {@link SoftReference} so that it
+     * it doesn't prevent any ClassLoader being garbage collected, but
+     * tries to re-create the method if the method reference has been
+     * released.
+     *
+     * See https://issues.apache.org/jira/browse/BEANUTILS-291
+     */
+    private static class MappedMethodReference {
+        private String className;
+        private String methodName;
+        private Reference<Method> methodRef;
+        private Reference<Class<?>> classRef;
+        private Reference<Class<?>> writeParamTypeRef0;
+        private Reference<Class<?>> writeParamTypeRef1;
+        private String[] writeParamClassNames;
+        MappedMethodReference(final Method m) {
+            if (m != null) {
+                className = m.getDeclaringClass().getName();
+                methodName = m.getName();
+                methodRef = new SoftReference<>(m);
+                classRef = new WeakReference<>(m.getDeclaringClass());
+                final Class<?>[] types = m.getParameterTypes();
+                if (types.length == 2) {
+                    writeParamTypeRef0 = new WeakReference<>(types[0]);
+                    writeParamTypeRef1 = new WeakReference<>(types[1]);
+                    writeParamClassNames = new String[2];
+                    writeParamClassNames[0] = types[0].getName();
+                    writeParamClassNames[1] = types[1].getName();
+                }
+            }
+        }
+        private Method get() {
+            if (methodRef == null) {
+                return null;
+            }
+            Method m = methodRef.get();
+            if (m == null) {
+                Class<?> clazz = classRef.get();
+                if (clazz == null) {
+                    clazz = reLoadClass();
+                    if (clazz != null) {
+                        classRef = new WeakReference<>(clazz);
+                    }
+                }
+                if (clazz == null) {
+                    throw new RuntimeException("Method " + methodName + " for " +
+                            className + " could not be reconstructed - class reference has gone");
+                }
+                Class<?>[] paramTypes = null;
+                if (writeParamClassNames != null) {
+                    paramTypes = new Class[2];
+                    paramTypes[0] = writeParamTypeRef0.get();
+                    if (paramTypes[0] == null) {
+                        paramTypes[0] = reLoadClass(writeParamClassNames[0]);
+                        if (paramTypes[0] != null) {
+                            writeParamTypeRef0 = new WeakReference<>(paramTypes[0]);
+                        }
+                    }
+                    paramTypes[1] = writeParamTypeRef1.get();
+                    if (paramTypes[1] == null) {
+                        paramTypes[1] = reLoadClass(writeParamClassNames[1]);
+                        if (paramTypes[1] != null) {
+                            writeParamTypeRef1 = new WeakReference<>(paramTypes[1]);
+                        }
+                    }
+                } else {
+                    paramTypes = STRING_CLASS_PARAMETER;
+                }
+                try {
+                    m = clazz.getMethod(methodName, paramTypes);
+                    // Un-comment following line for testing
+                    // System.out.println("Recreated Method " + methodName + " for " + className);
+                } catch (final NoSuchMethodException e) {
+                    throw new RuntimeException("Method " + methodName + " for " +
+                            className + " could not be reconstructed - method not found");
+                }
+                methodRef = new SoftReference<>(m);
+            }
+            return m;
+        }
+
+        /**
+         * Try to re-load the class
+         */
+        private Class<?> reLoadClass() {
+            return reLoadClass(className);
+        }
+
+        /**
+         * Try to re-load the class
+         */
+        private Class<?> reLoadClass(final String name) {
+
+            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+            // Try the context class loader
+            if (classLoader != null) {
+                try {
+                    return classLoader.loadClass(name);
+                } catch (final ClassNotFoundException e) {
+                    // ignore
+                }
+            }
+
+            // Try this class's class loader
+            classLoader = MappedPropertyDescriptor.class.getClassLoader();
+            try {
+                return classLoader.loadClass(name);
+            } catch (final ClassNotFoundException e) {
+                return null;
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/beanutils2/WrapDynaClass.java b/src/main/java/org/apache/commons/beanutils2/WrapDynaClass.java
index 00f1008..2d298b4 100644
--- a/src/main/java/org/apache/commons/beanutils2/WrapDynaClass.java
+++ b/src/main/java/org/apache/commons/beanutils2/WrapDynaClass.java
@@ -58,7 +58,7 @@
      */
     private WrapDynaClass(final Class<?> beanClass, final PropertyUtilsBean propUtils) {
 
-        this.beanClassRef = new SoftReference<Class<?>>(beanClass);
+        this.beanClassRef = new SoftReference<>(beanClass);
         this.beanClassName = beanClass.getName();
         propertyUtilsBean = propUtils;
         introspect();
diff --git a/src/test/java/org/apache/commons/beanutils2/BeanificationTestCase.java b/src/test/java/org/apache/commons/beanutils2/BeanificationTestCase.java
index 18ae331..a2381b3 100644
--- a/src/test/java/org/apache/commons/beanutils2/BeanificationTestCase.java
+++ b/src/test/java/org/apache/commons/beanutils2/BeanificationTestCase.java
@@ -1,544 +1,544 @@
-/*
- * 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.commons.beanutils2;
-
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.apache.commons.logging.LogFactory;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * <p>
- * Test Case for changes made during Beanutils Beanification
- * </p>
- *
- */
-
-public class BeanificationTestCase extends TestCase {
-
-    // ---------------------------------------------------- Constants
-
-    /** Maximum number of iterations before our test fails */
-    public static final int MAX_GC_ITERATIONS = 50;
-
-    // ---------------------------------------------------- Instance Variables
-
-
-    // ---------------------------------------------------------- Constructors
-
-
-    /**
-     * Construct a new instance of this test case.
-     *
-     * @param name Name of the test case
-     */
-    public BeanificationTestCase(final String name) {
-        super(name);
-    }
-
-
-    // -------------------------------------------------- Overall Test Methods
-
-
-    /**
-     * Set up instance variables required by this test case.
-     */
-    @Override
-    public void setUp() {
-
-        ConvertUtils.deregister();
-
-    }
-
-
-    /**
-     * Return the tests included in this test suite.
-     */
-    public static Test suite() {
-        return new TestSuite(BeanificationTestCase.class);
-    }
-
-
-    /**
-     * Tear down instance variables required by this test case.
-     */
-    @Override
-    public void tearDown() {
-        // No action required
-    }
-
-
-    // ------------------------------------------------ Individual Test Methods
-
-    /** Test of the methodology we'll use for some of the later tests */
-    public void testMemoryTestMethodology() throws Exception {
-        // test methodology
-        // many thanks to Juozas Baliuka for suggesting this method
-        ClassLoader loader = new ClassLoader(this.getClass().getClassLoader()) {};
-        final WeakReference<ClassLoader> reference = new  WeakReference<>(loader);
-        @SuppressWarnings("unused")
-        Class<?> myClass = loader.loadClass("org.apache.commons.beanutils2.BetaBean");
-
-        assertNotNull("Weak reference released early", reference.get());
-
-        // dereference class loader and class:
-        loader = null;
-        myClass = null;
-
-        int iterations = 0;
-        int bytz = 2;
-        while(true) {
-            System.gc();
-            if(iterations++ > MAX_GC_ITERATIONS){
-                fail("Max iterations reached before resource released.");
-            }
-            if( reference.get() == null ) {
-                break;
-
-            }
-            // create garbage:
-            @SuppressWarnings("unused")
-            final
-            byte[] b =  new byte[bytz];
-            bytz = bytz * 2;
-        }
-    }
-
-    /** Tests whether classloaders and beans are released from memory by the map used by beanutils */
-    public void testMemoryLeak2() throws Exception {
-        // tests when the map used by beanutils has the right behaviour
-
-        if (BeanUtilsTestCase.isPre14JVM()) {
-            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
-            return;
-        }
-
-        // many thanks to Juozas Baliuka for suggesting this methodology
-        TestClassLoader loader = new TestClassLoader();
-        final ReferenceQueue<Object> queue = new ReferenceQueue<>();
-        final WeakReference<ClassLoader> loaderReference = new WeakReference<ClassLoader>(loader, queue);
-        Integer test = new Integer(1);
-
-        final WeakReference<Integer> testReference = new WeakReference<>(test, queue);
-        //Map map = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD, true);
-        final Map<Object, Object> map = new WeakHashMap<>();
-        map.put(loader, test);
-
-        assertEquals("In map", test, map.get(loader));
-        assertNotNull("Weak reference released early (1)", loaderReference.get());
-        assertNotNull("Weak reference released early (2)", testReference.get());
-
-        // dereference strong references
-        loader = null;
-        test = null;
-
-        int iterations = 0;
-        int bytz = 2;
-        while(true) {
-            System.gc();
-            if(iterations++ > MAX_GC_ITERATIONS){
-                fail("Max iterations reached before resource released.");
-            }
-            map.isEmpty();
-
-            if(
-                loaderReference.get() == null &&
-                testReference.get() == null) {
-                break;
-
-            }
-            // create garbage:
-            @SuppressWarnings("unused")
-            final
-            byte[] b =  new byte[bytz];
-            bytz = bytz * 2;
-        }
-    }
-
-    /** Tests whether classloaders and beans are released from memory */
-    public void testMemoryLeak() throws Exception {
-        if (BeanUtilsTestCase.isPre14JVM()) {
-            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
-            return;
-        }
-
-        // many thanks to Juozas Baliuka for suggesting this methodology
-        TestClassLoader loader = new TestClassLoader();
-        final WeakReference<ClassLoader> loaderReference = new  WeakReference<ClassLoader>(loader);
-        BeanUtilsBean.getInstance();
-
-        class GetBeanUtilsBeanThread extends Thread {
-
-            BeanUtilsBean beanUtils;
-            ConvertUtilsBean convertUtils;
-            PropertyUtilsBean propertyUtils;
-
-            GetBeanUtilsBeanThread() {}
-
-            @Override
-            public void run() {
-                beanUtils = BeanUtilsBean.getInstance();
-                convertUtils = ConvertUtilsBean.getInstance();
-                propertyUtils = PropertyUtilsBean.getInstance();
-                // XXX Log keeps a reference around!
-                LogFactory.releaseAll();
-            }
-
-            @Override
-            public String toString() {
-                return "GetBeanUtilsBeanThread";
-            }
-        }
-
-
-        GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread();
-        @SuppressWarnings("unused")
-        final
-        WeakReference<Thread> threadWeakReference = new WeakReference<Thread>(thread);
-        thread.setContextClassLoader(loader);
-
-        thread.start();
-        thread.join();
-
-        final WeakReference<BeanUtilsBean> beanUtilsReference = new WeakReference<>(thread.beanUtils);
-        final WeakReference<PropertyUtilsBean> propertyUtilsReference =  new WeakReference<>(thread.propertyUtils);
-        final WeakReference<ConvertUtilsBean> convertUtilsReference = new WeakReference<>(thread.convertUtils);
-
-        assertNotNull("Weak reference released early (1)", loaderReference.get());
-        assertNotNull("Weak reference released early (2)", beanUtilsReference.get());
-        assertNotNull("Weak reference released early (3)", propertyUtilsReference.get());
-        assertNotNull("Weak reference released early (4)", convertUtilsReference.get());
-
-        // dereference strong references
-        loader = null;
-        thread.setContextClassLoader(null);
-        thread = null;
-
-        int iterations = 0;
-        int bytz = 2;
-        while(true) {
-            BeanUtilsBean.getInstance();
-            System.gc();
-            if(iterations++ > MAX_GC_ITERATIONS){
-                fail("Max iterations reached before resource released.");
-            }
-
-            if(
-                loaderReference.get() == null &&
-                beanUtilsReference.get() == null &&
-                propertyUtilsReference.get() == null &&
-                convertUtilsReference.get() == null) {
-                break;
-
-            }
-            // create garbage:
-            @SuppressWarnings("unused")
-            final
-            byte[] b =  new byte[bytz];
-            bytz = bytz * 2;
-        }
-    }
-
-    /**
-     * Tests whether difference instances are loaded by different
-     * context classloaders.
-     */
-    public void testGetByContextClassLoader() throws Exception {
-
-        class GetBeanUtilsBeanThread extends Thread {
-
-            private final Signal signal;
-
-            GetBeanUtilsBeanThread(final Signal signal) {
-                this.signal = signal;
-            }
-
-            @Override
-            public void run() {
-                signal.setSignal(2);
-                signal.setBean(BeanUtilsBean.getInstance());
-                signal.setConvertUtils(ConvertUtilsBean.getInstance());
-                signal.setPropertyUtils(PropertyUtilsBean.getInstance());
-            }
-
-            @Override
-            public String toString() {
-                return "GetBeanUtilsBeanThread";
-            }
-        }
-
-        final Signal signal = new Signal();
-        signal.setSignal(1);
-
-        final GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread(signal);
-        thread.setContextClassLoader(new TestClassLoader());
-
-        thread.start();
-        thread.join();
-
-        assertEquals("Signal not set by test thread", 2, signal.getSignal());
-        assertTrue(
-                    "Different BeanUtilsBean instances per context classloader",
-                    BeanUtilsBean.getInstance() != signal.getBean());
-        assertTrue(
-                    "Different ConvertUtilsBean instances per context classloader",
-                    ConvertUtilsBean.getInstance() != signal.getConvertUtils());
-        assertTrue(
-                    "Different PropertyUtilsBean instances per context classloader",
-                    PropertyUtilsBean.getInstance() != signal.getPropertyUtils());
-    }
-
-
-    /**
-     * Tests whether difference instances are loaded by different
-     * context classloaders.
-     */
-    public void testContextClassLoaderLocal() throws Exception {
-
-        class CCLLTesterThread extends Thread {
-
-            private final Signal signal;
-            private final ContextClassLoaderLocal<Integer> ccll;
-
-            CCLLTesterThread(final Signal signal, final ContextClassLoaderLocal<Integer> ccll) {
-                this.signal = signal;
-                this.ccll = ccll;
-            }
-
-            @Override
-            public void run() {
-                ccll.set(new Integer(1789));
-                signal.setSignal(2);
-                signal.setMarkerObject(ccll.get());
-            }
-
-            @Override
-            public String toString() {
-                return "CCLLTesterThread";
-            }
-        }
-
-        final ContextClassLoaderLocal<Integer> ccll = new ContextClassLoaderLocal<>();
-        ccll.set(new Integer(1776));
-        assertEquals("Start thread sets value", new Integer(1776), ccll.get());
-
-        final Signal signal = new Signal();
-        signal.setSignal(1);
-
-        final CCLLTesterThread thread = new CCLLTesterThread(signal, ccll);
-        thread.setContextClassLoader(new TestClassLoader());
-
-        thread.start();
-        thread.join();
-
-        assertEquals("Signal not set by test thread", 2, signal.getSignal());
-        assertEquals("Second thread preserves value", new Integer(1776), ccll.get());
-        assertEquals("Second thread gets value it set", new Integer(1789), signal.getMarkerObject());
-    }
-
-    /** Tests whether calls are independent for different classloaders */
-    public void testContextClassloaderIndependence() throws Exception {
-
-        class TestIndependenceThread extends Thread {
-            private final Signal signal;
-            private final PrimitiveBean bean;
-
-            TestIndependenceThread(final Signal signal, final PrimitiveBean bean) {
-                this.signal = signal;
-                this.bean = bean;
-            }
-
-            @Override
-            public void run() {
-                try {
-                    signal.setSignal(3);
-                    ConvertUtils.register(new Converter() {
-                                            @Override
-                                            public <T> T convert(final Class<T> type, final Object value) {
-                                                return ConvertUtils.primitiveToWrapper(type).cast(new Integer(9));
-                                            }
-                                                }, Integer.TYPE);
-                    BeanUtils.setProperty(bean, "int", new Integer(1));
-                } catch (final Exception e) {
-                    e.printStackTrace();
-                    signal.setException(e);
-                }
-            }
-
-            @Override
-            public String toString() {
-                return "TestIndependenceThread";
-            }
-        }
-
-        final PrimitiveBean bean = new PrimitiveBean();
-        BeanUtils.setProperty(bean, "int", new Integer(1));
-        assertEquals("Wrong property value (1)", 1, bean.getInt());
-
-        ConvertUtils.register(new Converter() {
-                                @Override
-                                public <T> T convert(final Class<T> type, final Object value) {
-                                    return ConvertUtils.primitiveToWrapper(type).cast(new Integer(5));
-                                }
-                                    }, Integer.TYPE);
-        BeanUtils.setProperty(bean, "int", new Integer(1));
-        assertEquals("Wrong property value(2)", 5, bean.getInt());
-
-        final Signal signal = new Signal();
-        signal.setSignal(1);
-        final TestIndependenceThread thread = new TestIndependenceThread(signal, bean);
-        thread.setContextClassLoader(new TestClassLoader());
-
-        thread.start();
-        thread.join();
-
-        assertNull("Exception thrown by test thread:" + signal.getException(), signal.getException());
-        assertEquals("Signal not set by test thread", 3, signal.getSignal());
-        assertEquals("Wrong property value(3)", 9, bean.getInt());
-
-    }
-
-    /** Tests whether different threads can set beanutils instances correctly */
-    public void testBeanUtilsBeanSetInstance() throws Exception {
-
-        class SetInstanceTesterThread extends Thread {
-
-            private final Signal signal;
-            private final BeanUtilsBean bean;
-
-            SetInstanceTesterThread(final Signal signal, final BeanUtilsBean bean) {
-                this.signal = signal;
-                this.bean = bean;
-            }
-
-            @Override
-            public void run() {
-                BeanUtilsBean.setInstance(bean);
-                signal.setSignal(21);
-                signal.setBean(BeanUtilsBean.getInstance());
-            }
-
-            @Override
-            public String toString() {
-                return "SetInstanceTesterThread";
-            }
-        }
-
-        final Signal signal = new Signal();
-        signal.setSignal(1);
-
-        final BeanUtilsBean beanOne = new BeanUtilsBean();
-        final BeanUtilsBean beanTwo = new BeanUtilsBean();
-
-        final SetInstanceTesterThread thread = new SetInstanceTesterThread(signal, beanTwo);
-        thread.setContextClassLoader(new TestClassLoader());
-
-        BeanUtilsBean.setInstance(beanOne);
-        assertEquals("Start thread gets right instance", beanOne, BeanUtilsBean.getInstance());
-
-        thread.start();
-        thread.join();
-
-        assertEquals("Signal not set by test thread", 21, signal.getSignal());
-        assertEquals("Second thread preserves value", beanOne, BeanUtilsBean.getInstance());
-        assertEquals("Second thread gets value it set", beanTwo, signal.getBean());
-    }
-
-    /** Tests whether the unset method works*/
-    public void testContextClassLoaderUnset() throws Exception {
-        final BeanUtilsBean beanOne = new BeanUtilsBean();
-        final ContextClassLoaderLocal<BeanUtilsBean> ccll = new ContextClassLoaderLocal<>();
-        ccll.set(beanOne);
-        assertEquals("Start thread gets right instance", beanOne, ccll.get());
-        ccll.unset();
-        assertTrue("Unset works", !beanOne.equals(ccll.get()));
-    }
-
-    // ---- Auxillary classes
-
-    class TestClassLoader extends ClassLoader {
-        @Override
-        public String toString() {
-            return "TestClassLoader";
-        }
-    }
-
-    class Signal {
-        private Exception e;
-        private int signal = 0;
-        private BeanUtilsBean bean;
-        private PropertyUtilsBean propertyUtils;
-        private ConvertUtilsBean convertUtils;
-        private Object marker;
-
-        public Exception getException() {
-            return e;
-        }
-
-        public void setException(final Exception e) {
-            this.e = e;
-        }
-
-        public int getSignal() {
-            return signal;
-        }
-
-        public void setSignal(final int signal) {
-            this.signal = signal;
-        }
-
-        public Object getMarkerObject() {
-            return marker;
-        }
-
-        public void setMarkerObject(final Object marker) {
-            this.marker = marker;
-        }
-
-        public BeanUtilsBean getBean() {
-            return bean;
-        }
-
-        public void setBean(final BeanUtilsBean bean) {
-            this.bean = bean;
-        }
-
-        public PropertyUtilsBean getPropertyUtils() {
-            return propertyUtils;
-        }
-
-        public void setPropertyUtils(final PropertyUtilsBean propertyUtils) {
-            this.propertyUtils = propertyUtils;
-        }
-
-        public ConvertUtilsBean getConvertUtils() {
-            return convertUtils;
-        }
-
-        public void setConvertUtils(final ConvertUtilsBean convertUtils) {
-            this.convertUtils = convertUtils;
-        }
-    }
-}
-
+/*
+ * 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.commons.beanutils2;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.apache.commons.logging.LogFactory;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ * Test Case for changes made during Beanutils Beanification
+ * </p>
+ *
+ */
+
+public class BeanificationTestCase extends TestCase {
+
+    // ---------------------------------------------------- Constants
+
+    /** Maximum number of iterations before our test fails */
+    public static final int MAX_GC_ITERATIONS = 50;
+
+    // ---------------------------------------------------- Instance Variables
+
+
+    // ---------------------------------------------------------- Constructors
+
+
+    /**
+     * Construct a new instance of this test case.
+     *
+     * @param name Name of the test case
+     */
+    public BeanificationTestCase(final String name) {
+        super(name);
+    }
+
+
+    // -------------------------------------------------- Overall Test Methods
+
+
+    /**
+     * Set up instance variables required by this test case.
+     */
+    @Override
+    public void setUp() {
+
+        ConvertUtils.deregister();
+
+    }
+
+
+    /**
+     * Return the tests included in this test suite.
+     */
+    public static Test suite() {
+        return new TestSuite(BeanificationTestCase.class);
+    }
+
+
+    /**
+     * Tear down instance variables required by this test case.
+     */
+    @Override
+    public void tearDown() {
+        // No action required
+    }
+
+
+    // ------------------------------------------------ Individual Test Methods
+
+    /** Test of the methodology we'll use for some of the later tests */
+    public void testMemoryTestMethodology() throws Exception {
+        // test methodology
+        // many thanks to Juozas Baliuka for suggesting this method
+        ClassLoader loader = new ClassLoader(this.getClass().getClassLoader()) {};
+        final WeakReference<ClassLoader> reference = new  WeakReference<>(loader);
+        @SuppressWarnings("unused")
+        Class<?> myClass = loader.loadClass("org.apache.commons.beanutils2.BetaBean");
+
+        assertNotNull("Weak reference released early", reference.get());
+
+        // dereference class loader and class:
+        loader = null;
+        myClass = null;
+
+        int iterations = 0;
+        int bytz = 2;
+        while(true) {
+            System.gc();
+            if(iterations++ > MAX_GC_ITERATIONS){
+                fail("Max iterations reached before resource released.");
+            }
+            if( reference.get() == null ) {
+                break;
+
+            }
+            // create garbage:
+            @SuppressWarnings("unused")
+            final
+            byte[] b =  new byte[bytz];
+            bytz = bytz * 2;
+        }
+    }
+
+    /** Tests whether classloaders and beans are released from memory by the map used by beanutils */
+    public void testMemoryLeak2() throws Exception {
+        // tests when the map used by beanutils has the right behaviour
+
+        if (BeanUtilsTestCase.isPre14JVM()) {
+            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
+            return;
+        }
+
+        // many thanks to Juozas Baliuka for suggesting this methodology
+        TestClassLoader loader = new TestClassLoader();
+        final ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        final WeakReference<ClassLoader> loaderReference = new WeakReference<>(loader, queue);
+        Integer test = new Integer(1);
+
+        final WeakReference<Integer> testReference = new WeakReference<>(test, queue);
+        //Map map = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD, true);
+        final Map<Object, Object> map = new WeakHashMap<>();
+        map.put(loader, test);
+
+        assertEquals("In map", test, map.get(loader));
+        assertNotNull("Weak reference released early (1)", loaderReference.get());
+        assertNotNull("Weak reference released early (2)", testReference.get());
+
+        // dereference strong references
+        loader = null;
+        test = null;
+
+        int iterations = 0;
+        int bytz = 2;
+        while(true) {
+            System.gc();
+            if(iterations++ > MAX_GC_ITERATIONS){
+                fail("Max iterations reached before resource released.");
+            }
+            map.isEmpty();
+
+            if(
+                loaderReference.get() == null &&
+                testReference.get() == null) {
+                break;
+
+            }
+            // create garbage:
+            @SuppressWarnings("unused")
+            final
+            byte[] b =  new byte[bytz];
+            bytz = bytz * 2;
+        }
+    }
+
+    /** Tests whether classloaders and beans are released from memory */
+    public void testMemoryLeak() throws Exception {
+        if (BeanUtilsTestCase.isPre14JVM()) {
+            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
+            return;
+        }
+
+        // many thanks to Juozas Baliuka for suggesting this methodology
+        TestClassLoader loader = new TestClassLoader();
+        final WeakReference<ClassLoader> loaderReference = new  WeakReference<>(loader);
+        BeanUtilsBean.getInstance();
+
+        class GetBeanUtilsBeanThread extends Thread {
+
+            BeanUtilsBean beanUtils;
+            ConvertUtilsBean convertUtils;
+            PropertyUtilsBean propertyUtils;
+
+            GetBeanUtilsBeanThread() {}
+
+            @Override
+            public void run() {
+                beanUtils = BeanUtilsBean.getInstance();
+                convertUtils = ConvertUtilsBean.getInstance();
+                propertyUtils = PropertyUtilsBean.getInstance();
+                // XXX Log keeps a reference around!
+                LogFactory.releaseAll();
+            }
+
+            @Override
+            public String toString() {
+                return "GetBeanUtilsBeanThread";
+            }
+        }
+
+
+        GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread();
+        @SuppressWarnings("unused")
+        final
+        WeakReference<Thread> threadWeakReference = new WeakReference<>(thread);
+        thread.setContextClassLoader(loader);
+
+        thread.start();
+        thread.join();
+
+        final WeakReference<BeanUtilsBean> beanUtilsReference = new WeakReference<>(thread.beanUtils);
+        final WeakReference<PropertyUtilsBean> propertyUtilsReference =  new WeakReference<>(thread.propertyUtils);
+        final WeakReference<ConvertUtilsBean> convertUtilsReference = new WeakReference<>(thread.convertUtils);
+
+        assertNotNull("Weak reference released early (1)", loaderReference.get());
+        assertNotNull("Weak reference released early (2)", beanUtilsReference.get());
+        assertNotNull("Weak reference released early (3)", propertyUtilsReference.get());
+        assertNotNull("Weak reference released early (4)", convertUtilsReference.get());
+
+        // dereference strong references
+        loader = null;
+        thread.setContextClassLoader(null);
+        thread = null;
+
+        int iterations = 0;
+        int bytz = 2;
+        while(true) {
+            BeanUtilsBean.getInstance();
+            System.gc();
+            if(iterations++ > MAX_GC_ITERATIONS){
+                fail("Max iterations reached before resource released.");
+            }
+
+            if(
+                loaderReference.get() == null &&
+                beanUtilsReference.get() == null &&
+                propertyUtilsReference.get() == null &&
+                convertUtilsReference.get() == null) {
+                break;
+
+            }
+            // create garbage:
+            @SuppressWarnings("unused")
+            final
+            byte[] b =  new byte[bytz];
+            bytz = bytz * 2;
+        }
+    }
+
+    /**
+     * Tests whether difference instances are loaded by different
+     * context classloaders.
+     */
+    public void testGetByContextClassLoader() throws Exception {
+
+        class GetBeanUtilsBeanThread extends Thread {
+
+            private final Signal signal;
+
+            GetBeanUtilsBeanThread(final Signal signal) {
+                this.signal = signal;
+            }
+
+            @Override
+            public void run() {
+                signal.setSignal(2);
+                signal.setBean(BeanUtilsBean.getInstance());
+                signal.setConvertUtils(ConvertUtilsBean.getInstance());
+                signal.setPropertyUtils(PropertyUtilsBean.getInstance());
+            }
+
+            @Override
+            public String toString() {
+                return "GetBeanUtilsBeanThread";
+            }
+        }
+
+        final Signal signal = new Signal();
+        signal.setSignal(1);
+
+        final GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread(signal);
+        thread.setContextClassLoader(new TestClassLoader());
+
+        thread.start();
+        thread.join();
+
+        assertEquals("Signal not set by test thread", 2, signal.getSignal());
+        assertTrue(
+                    "Different BeanUtilsBean instances per context classloader",
+                    BeanUtilsBean.getInstance() != signal.getBean());
+        assertTrue(
+                    "Different ConvertUtilsBean instances per context classloader",
+                    ConvertUtilsBean.getInstance() != signal.getConvertUtils());
+        assertTrue(
+                    "Different PropertyUtilsBean instances per context classloader",
+                    PropertyUtilsBean.getInstance() != signal.getPropertyUtils());
+    }
+
+
+    /**
+     * Tests whether difference instances are loaded by different
+     * context classloaders.
+     */
+    public void testContextClassLoaderLocal() throws Exception {
+
+        class CCLLTesterThread extends Thread {
+
+            private final Signal signal;
+            private final ContextClassLoaderLocal<Integer> ccll;
+
+            CCLLTesterThread(final Signal signal, final ContextClassLoaderLocal<Integer> ccll) {
+                this.signal = signal;
+                this.ccll = ccll;
+            }
+
+            @Override
+            public void run() {
+                ccll.set(new Integer(1789));
+                signal.setSignal(2);
+                signal.setMarkerObject(ccll.get());
+            }
+
+            @Override
+            public String toString() {
+                return "CCLLTesterThread";
+            }
+        }
+
+        final ContextClassLoaderLocal<Integer> ccll = new ContextClassLoaderLocal<>();
+        ccll.set(new Integer(1776));
+        assertEquals("Start thread sets value", new Integer(1776), ccll.get());
+
+        final Signal signal = new Signal();
+        signal.setSignal(1);
+
+        final CCLLTesterThread thread = new CCLLTesterThread(signal, ccll);
+        thread.setContextClassLoader(new TestClassLoader());
+
+        thread.start();
+        thread.join();
+
+        assertEquals("Signal not set by test thread", 2, signal.getSignal());
+        assertEquals("Second thread preserves value", new Integer(1776), ccll.get());
+        assertEquals("Second thread gets value it set", new Integer(1789), signal.getMarkerObject());
+    }
+
+    /** Tests whether calls are independent for different classloaders */
+    public void testContextClassloaderIndependence() throws Exception {
+
+        class TestIndependenceThread extends Thread {
+            private final Signal signal;
+            private final PrimitiveBean bean;
+
+            TestIndependenceThread(final Signal signal, final PrimitiveBean bean) {
+                this.signal = signal;
+                this.bean = bean;
+            }
+
+            @Override
+            public void run() {
+                try {
+                    signal.setSignal(3);
+                    ConvertUtils.register(new Converter() {
+                                            @Override
+                                            public <T> T convert(final Class<T> type, final Object value) {
+                                                return ConvertUtils.primitiveToWrapper(type).cast(new Integer(9));
+                                            }
+                                                }, Integer.TYPE);
+                    BeanUtils.setProperty(bean, "int", new Integer(1));
+                } catch (final Exception e) {
+                    e.printStackTrace();
+                    signal.setException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "TestIndependenceThread";
+            }
+        }
+
+        final PrimitiveBean bean = new PrimitiveBean();
+        BeanUtils.setProperty(bean, "int", new Integer(1));
+        assertEquals("Wrong property value (1)", 1, bean.getInt());
+
+        ConvertUtils.register(new Converter() {
+                                @Override
+                                public <T> T convert(final Class<T> type, final Object value) {
+                                    return ConvertUtils.primitiveToWrapper(type).cast(new Integer(5));
+                                }
+                                    }, Integer.TYPE);
+        BeanUtils.setProperty(bean, "int", new Integer(1));
+        assertEquals("Wrong property value(2)", 5, bean.getInt());
+
+        final Signal signal = new Signal();
+        signal.setSignal(1);
+        final TestIndependenceThread thread = new TestIndependenceThread(signal, bean);
+        thread.setContextClassLoader(new TestClassLoader());
+
+        thread.start();
+        thread.join();
+
+        assertNull("Exception thrown by test thread:" + signal.getException(), signal.getException());
+        assertEquals("Signal not set by test thread", 3, signal.getSignal());
+        assertEquals("Wrong property value(3)", 9, bean.getInt());
+
+    }
+
+    /** Tests whether different threads can set beanutils instances correctly */
+    public void testBeanUtilsBeanSetInstance() throws Exception {
+
+        class SetInstanceTesterThread extends Thread {
+
+            private final Signal signal;
+            private final BeanUtilsBean bean;
+
+            SetInstanceTesterThread(final Signal signal, final BeanUtilsBean bean) {
+                this.signal = signal;
+                this.bean = bean;
+            }
+
+            @Override
+            public void run() {
+                BeanUtilsBean.setInstance(bean);
+                signal.setSignal(21);
+                signal.setBean(BeanUtilsBean.getInstance());
+            }
+
+            @Override
+            public String toString() {
+                return "SetInstanceTesterThread";
+            }
+        }
+
+        final Signal signal = new Signal();
+        signal.setSignal(1);
+
+        final BeanUtilsBean beanOne = new BeanUtilsBean();
+        final BeanUtilsBean beanTwo = new BeanUtilsBean();
+
+        final SetInstanceTesterThread thread = new SetInstanceTesterThread(signal, beanTwo);
+        thread.setContextClassLoader(new TestClassLoader());
+
+        BeanUtilsBean.setInstance(beanOne);
+        assertEquals("Start thread gets right instance", beanOne, BeanUtilsBean.getInstance());
+
+        thread.start();
+        thread.join();
+
+        assertEquals("Signal not set by test thread", 21, signal.getSignal());
+        assertEquals("Second thread preserves value", beanOne, BeanUtilsBean.getInstance());
+        assertEquals("Second thread gets value it set", beanTwo, signal.getBean());
+    }
+
+    /** Tests whether the unset method works*/
+    public void testContextClassLoaderUnset() throws Exception {
+        final BeanUtilsBean beanOne = new BeanUtilsBean();
+        final ContextClassLoaderLocal<BeanUtilsBean> ccll = new ContextClassLoaderLocal<>();
+        ccll.set(beanOne);
+        assertEquals("Start thread gets right instance", beanOne, ccll.get());
+        ccll.unset();
+        assertTrue("Unset works", !beanOne.equals(ccll.get()));
+    }
+
+    // ---- Auxillary classes
+
+    class TestClassLoader extends ClassLoader {
+        @Override
+        public String toString() {
+            return "TestClassLoader";
+        }
+    }
+
+    class Signal {
+        private Exception e;
+        private int signal = 0;
+        private BeanUtilsBean bean;
+        private PropertyUtilsBean propertyUtils;
+        private ConvertUtilsBean convertUtils;
+        private Object marker;
+
+        public Exception getException() {
+            return e;
+        }
+
+        public void setException(final Exception e) {
+            this.e = e;
+        }
+
+        public int getSignal() {
+            return signal;
+        }
+
+        public void setSignal(final int signal) {
+            this.signal = signal;
+        }
+
+        public Object getMarkerObject() {
+            return marker;
+        }
+
+        public void setMarkerObject(final Object marker) {
+            this.marker = marker;
+        }
+
+        public BeanUtilsBean getBean() {
+            return bean;
+        }
+
+        public void setBean(final BeanUtilsBean bean) {
+            this.bean = bean;
+        }
+
+        public PropertyUtilsBean getPropertyUtils() {
+            return propertyUtils;
+        }
+
+        public void setPropertyUtils(final PropertyUtilsBean propertyUtils) {
+            this.propertyUtils = propertyUtils;
+        }
+
+        public ConvertUtilsBean getConvertUtils() {
+            return convertUtils;
+        }
+
+        public void setConvertUtils(final ConvertUtilsBean convertUtils) {
+            this.convertUtils = convertUtils;
+        }
+    }
+}
+
diff --git a/src/test/java/org/apache/commons/beanutils2/converters/MemoryTestCase.java b/src/test/java/org/apache/commons/beanutils2/converters/MemoryTestCase.java
index dc6ffcc..15e8480 100644
--- a/src/test/java/org/apache/commons/beanutils2/converters/MemoryTestCase.java
+++ b/src/test/java/org/apache/commons/beanutils2/converters/MemoryTestCase.java
@@ -1,291 +1,291 @@
-/*
- * 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.commons.beanutils2.converters;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.lang.ref.WeakReference;
-
-import org.apache.commons.beanutils2.ConvertUtils;
-import org.apache.commons.beanutils2.Converter;
-import org.junit.Test;
-
-/**
- * This class provides a number of unit tests related to classloaders and
- * garbage collection, particularly in j2ee-like situations.
- *
- */
-public class MemoryTestCase {
-
-    @Test
-    public void testWeakReference() throws Exception {
-        final ClassLoader origContextClassLoader = Thread.currentThread().getContextClassLoader();
-        try {
-        ClassReloader componentLoader = new ClassReloader(origContextClassLoader);
-
-        Thread.currentThread().setContextClassLoader(componentLoader);
-        Thread.currentThread().setContextClassLoader(origContextClassLoader);
-
-        final WeakReference<ClassLoader> ref = new WeakReference<ClassLoader>(componentLoader);
-        componentLoader = null;
-
-        forceGarbageCollection(ref);
-        assertNull(ref.get());
-        } finally {
-            // Restore context classloader that was present before this
-            // test started. It is expected to be the same as the system
-            // classloader, but we handle all cases here..
-            Thread.currentThread().setContextClassLoader(origContextClassLoader);
-
-            // and restore all the standard converters
-            ConvertUtils.deregister();
-        }
-    }
-
-    /**
-     * Test whether registering a standard Converter instance while
-     * a custom context classloader is set causes a memory leak.
-     *
-     * <p>This test emulates a j2ee container where BeanUtils has been
-     * loaded from a "common" lib location that is shared across all
-     * components running within the container. The "component" registers
-     * a converter object, whose class was loaded from the "common" lib
-     * location. The registered converter:
-     * <ul>
-     * <li>should not be visible to other components; and</li>
-     * <li>should not prevent the component-specific classloader from being
-     *  garbage-collected when the container sets its reference to null.
-     * </ul>
-     *
-     */
-    @Test
-    public void testComponentRegistersStandardConverter() throws Exception {
-
-        final ClassLoader origContextClassLoader = Thread.currentThread().getContextClassLoader();
-        try {
-            // sanity check; who's paranoid?? :-)
-            assertEquals(origContextClassLoader, ConvertUtils.class.getClassLoader());
-
-            // create a custom classloader for a "component"
-            // just like a container would.
-            ClassLoader componentLoader1 = new ClassLoader() {};
-            final ClassLoader componentLoader2 = new ClassLoader() {};
-
-            final Converter origFloatConverter = ConvertUtils.lookup(Float.TYPE);
-            final Converter floatConverter1 = new FloatConverter();
-
-            // Emulate the container invoking a component #1, and the component
-            // registering a custom converter instance whose class is
-            // available via the "shared" classloader.
-            Thread.currentThread().setContextClassLoader(componentLoader1);
-            {
-                // here we pretend we're running inside component #1
-
-                // When we first do a ConvertUtils operation inside a custom
-                // classloader, we get a completely fresh copy of the
-                // ConvertUtilsBean, with all-new Converter objects in it..
-                assertFalse(ConvertUtils.lookup(Float.TYPE) == origFloatConverter);
-
-                // Now we register a custom converter (but of a standard class).
-                // This should only affect code that runs with exactly the
-                // same context classloader set.
-                ConvertUtils.register(floatConverter1, Float.TYPE);
-                assertTrue(ConvertUtils.lookup(Float.TYPE) == floatConverter1);
-            }
-            Thread.currentThread().setContextClassLoader(origContextClassLoader);
-
-            // The converter visible outside any custom component should not
-            // have been altered.
-            assertTrue(ConvertUtils.lookup(Float.TYPE) == origFloatConverter);
-
-            // Emulate the container invoking a component #2.
-            Thread.currentThread().setContextClassLoader(componentLoader2);
-            {
-                // here we pretend we're running inside component #2
-
-                // we should get a completely fresh ConvertUtilsBean, with
-                // all-new Converter objects again.
-                assertFalse(ConvertUtils.lookup(Float.TYPE) == origFloatConverter);
-                assertFalse(ConvertUtils.lookup(Float.TYPE) == floatConverter1);
-            }
-            Thread.currentThread().setContextClassLoader(origContextClassLoader);
-
-            // Emulate a container "undeploying" component #1. This should
-            // make component loader available for garbage collection (we hope)
-            final WeakReference<ClassLoader> weakRefToComponent1 = new WeakReference<>(componentLoader1);
-            componentLoader1 = null;
-
-            // force garbage collection and  verify that the componentLoader
-            // has been garbage-collected
-            forceGarbageCollection(weakRefToComponent1);
-            assertNull(
-                "Component classloader did not release properly; memory leak present",
-                weakRefToComponent1.get());
-        } finally {
-            // Restore context classloader that was present before this
-            // test started, so that in case of a test failure we don't stuff
-            // up later tests...
-            Thread.currentThread().setContextClassLoader(origContextClassLoader);
-
-            // and restore all the standard converters
-            ConvertUtils.deregister();
-        }
-    }
-
-    /**
-     * Test whether registering a custom Converter subclass while
-     * a custom context classloader is set causes a memory leak.
-     *
-     * <p>This test emulates a j2ee container where BeanUtils has been
-     * loaded from a "common" lib location that is shared across all
-     * components running within the container. The "component" registers
-     * a converter object, whose class was loaded via the component-specific
-     * classloader. The registered converter:
-     * <ul>
-     * <li>should not be visible to other components; and</li>
-     * <li>should not prevent the component-specific classloader from being
-     *  garbage-collected when the container sets its reference to null.
-     * </ul>
-     *
-     */
-    @Test
-    public void testComponentRegistersCustomConverter() throws Exception {
-
-        final ClassLoader origContextClassLoader = Thread.currentThread().getContextClassLoader();
-        try {
-            // sanity check; who's paranoid?? :-)
-            assertEquals(origContextClassLoader, ConvertUtils.class.getClassLoader());
-
-            // create a custom classloader for a "component"
-            // just like a container would.
-            ClassReloader componentLoader = new ClassReloader(origContextClassLoader);
-
-            // Load a custom Converter via component loader. This emulates what
-            // would happen if a user wrote their own FloatConverter subclass
-            // and deployed it via the component-specific classpath.
-            Thread.currentThread().setContextClassLoader(componentLoader);
-            {
-              // Here we pretend we're running inside the component, and that
-              // a class FloatConverter has been loaded from the component's
-              // private classpath.
-              final Class<?> newFloatConverterClass = componentLoader.reload(FloatConverter.class);
-              Object newFloatConverter = newFloatConverterClass.newInstance();
-              assertTrue(newFloatConverter.getClass().getClassLoader() == componentLoader);
-
-              // verify that this new object does implement the Converter type
-              // despite being loaded via a classloader different from the one
-              // that loaded the Converter class.
-              assertTrue(
-                "Converter loader via child does not implement parent type",
-                Converter.class.isInstance(newFloatConverter));
-
-              // this converter registration will only apply to the
-              // componentLoader classloader...
-              ConvertUtils.register((Converter)newFloatConverter, Float.TYPE);
-
-              // After registering a custom converter, lookup should return
-              // it back to us. We'll try this lookup again with a different
-              // context-classloader set, and shouldn't see it
-              final Converter componentConverter = ConvertUtils.lookup(Float.TYPE);
-              assertTrue(componentConverter.getClass().getClassLoader() == componentLoader);
-
-              newFloatConverter = null;
-            }
-            Thread.currentThread().setContextClassLoader(origContextClassLoader);
-
-            // Because the context classloader has been reset, we shouldn't
-            // see the custom registered converter here...
-            final Converter sharedConverter = ConvertUtils.lookup(Float.TYPE);
-            assertFalse(sharedConverter.getClass().getClassLoader() == componentLoader);
-
-            // and here we should see it again
-            Thread.currentThread().setContextClassLoader(componentLoader);
-            {
-                final Converter componentConverter = ConvertUtils.lookup(Float.TYPE);
-                assertTrue(componentConverter.getClass().getClassLoader() == componentLoader);
-            }
-            Thread.currentThread().setContextClassLoader(origContextClassLoader);
-            // Emulate a container "undeploying" the component. This should
-            // make component loader available for garbage collection (we hope)
-            final WeakReference<ClassLoader> weakRefToComponent = new WeakReference<ClassLoader>(componentLoader);
-            componentLoader = null;
-
-            // force garbage collection and  verify that the componentLoader
-            // has been garbage-collected
-            forceGarbageCollection(weakRefToComponent);
-            assertNull(
-                "Component classloader did not release properly; memory leak present",
-                weakRefToComponent.get());
-        } finally {
-            // Restore context classloader that was present before this
-            // test started. It is expected to be the same as the system
-            // classloader, but we handle all cases here..
-            Thread.currentThread().setContextClassLoader(origContextClassLoader);
-
-            // and restore all the standard converters
-            ConvertUtils.deregister();
-        }
-    }
-
-    /**
-     * Attempt to force garbage collection of the specified target.
-     *
-     * <p>Unfortunately there is no way to force a JVM to perform
-     * garbage collection; all we can do is <i>hint</i> to it that
-     * garbage-collection would be a good idea, and to consume
-     * memory in order to trigger it.</p>
-     *
-     * <p>On return, target.get() will return null if the target has
-     * been garbage collected.</p>
-     *
-     * <p>If target.get() still returns non-null after this method has returned,
-     * then either there is some reference still being held to the target, or
-     * else we were not able to trigger garbage collection; there is no way
-     * to tell these scenarios apart.</p>
-     */
-    private void forceGarbageCollection(final WeakReference<?> target) {
-        int bytes = 2;
-
-        while(target.get() != null) {
-            System.gc();
-
-            // Create increasingly-large amounts of non-referenced memory
-            // in order to persuade the JVM to collect it. We are hoping
-            // here that the JVM is dumb enough to run a full gc pass over
-            // all data (including the target) rather than simply collecting
-            // this easily-reclaimable memory!
-            try {
-                @SuppressWarnings("unused")
-                final
-                byte[] b = new byte[bytes];
-                bytes = bytes * 2;
-            } catch(final OutOfMemoryError e) {
-                // well that sure should have forced a garbage collection
-                // run to occur!
-                break;
-            }
-        }
-
-        // and let's do one more just to clean up any garbage we might have
-        // created on the last pass..
-        System.gc();
-    }
-}
+/*
+ * 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.commons.beanutils2.converters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.ref.WeakReference;
+
+import org.apache.commons.beanutils2.ConvertUtils;
+import org.apache.commons.beanutils2.Converter;
+import org.junit.Test;
+
+/**
+ * This class provides a number of unit tests related to classloaders and
+ * garbage collection, particularly in j2ee-like situations.
+ *
+ */
+public class MemoryTestCase {
+
+    @Test
+    public void testWeakReference() throws Exception {
+        final ClassLoader origContextClassLoader = Thread.currentThread().getContextClassLoader();
+        try {
+        ClassReloader componentLoader = new ClassReloader(origContextClassLoader);
+
+        Thread.currentThread().setContextClassLoader(componentLoader);
+        Thread.currentThread().setContextClassLoader(origContextClassLoader);
+
+        final WeakReference<ClassLoader> ref = new WeakReference<>(componentLoader);
+        componentLoader = null;
+
+        forceGarbageCollection(ref);
+        assertNull(ref.get());
+        } finally {
+            // Restore context classloader that was present before this
+            // test started. It is expected to be the same as the system
+            // classloader, but we handle all cases here..
+            Thread.currentThread().setContextClassLoader(origContextClassLoader);
+
+            // and restore all the standard converters
+            ConvertUtils.deregister();
+        }
+    }
+
+    /**
+     * Test whether registering a standard Converter instance while
+     * a custom context classloader is set causes a memory leak.
+     *
+     * <p>This test emulates a j2ee container where BeanUtils has been
+     * loaded from a "common" lib location that is shared across all
+     * components running within the container. The "component" registers
+     * a converter object, whose class was loaded from the "common" lib
+     * location. The registered converter:
+     * <ul>
+     * <li>should not be visible to other components; and</li>
+     * <li>should not prevent the component-specific classloader from being
+     *  garbage-collected when the container sets its reference to null.
+     * </ul>
+     *
+     */
+    @Test
+    public void testComponentRegistersStandardConverter() throws Exception {
+
+        final ClassLoader origContextClassLoader = Thread.currentThread().getContextClassLoader();
+        try {
+            // sanity check; who's paranoid?? :-)
+            assertEquals(origContextClassLoader, ConvertUtils.class.getClassLoader());
+
+            // create a custom classloader for a "component"
+            // just like a container would.
+            ClassLoader componentLoader1 = new ClassLoader() {};
+            final ClassLoader componentLoader2 = new ClassLoader() {};
+
+            final Converter origFloatConverter = ConvertUtils.lookup(Float.TYPE);
+            final Converter floatConverter1 = new FloatConverter();
+
+            // Emulate the container invoking a component #1, and the component
+            // registering a custom converter instance whose class is
+            // available via the "shared" classloader.
+            Thread.currentThread().setContextClassLoader(componentLoader1);
+            {
+                // here we pretend we're running inside component #1
+
+                // When we first do a ConvertUtils operation inside a custom
+                // classloader, we get a completely fresh copy of the
+                // ConvertUtilsBean, with all-new Converter objects in it..
+                assertFalse(ConvertUtils.lookup(Float.TYPE) == origFloatConverter);
+
+                // Now we register a custom converter (but of a standard class).
+                // This should only affect code that runs with exactly the
+                // same context classloader set.
+                ConvertUtils.register(floatConverter1, Float.TYPE);
+                assertTrue(ConvertUtils.lookup(Float.TYPE) == floatConverter1);
+            }
+            Thread.currentThread().setContextClassLoader(origContextClassLoader);
+
+            // The converter visible outside any custom component should not
+            // have been altered.
+            assertTrue(ConvertUtils.lookup(Float.TYPE) == origFloatConverter);
+
+            // Emulate the container invoking a component #2.
+            Thread.currentThread().setContextClassLoader(componentLoader2);
+            {
+                // here we pretend we're running inside component #2
+
+                // we should get a completely fresh ConvertUtilsBean, with
+                // all-new Converter objects again.
+                assertFalse(ConvertUtils.lookup(Float.TYPE) == origFloatConverter);
+                assertFalse(ConvertUtils.lookup(Float.TYPE) == floatConverter1);
+            }
+            Thread.currentThread().setContextClassLoader(origContextClassLoader);
+
+            // Emulate a container "undeploying" component #1. This should
+            // make component loader available for garbage collection (we hope)
+            final WeakReference<ClassLoader> weakRefToComponent1 = new WeakReference<>(componentLoader1);
+            componentLoader1 = null;
+
+            // force garbage collection and  verify that the componentLoader
+            // has been garbage-collected
+            forceGarbageCollection(weakRefToComponent1);
+            assertNull(
+                "Component classloader did not release properly; memory leak present",
+                weakRefToComponent1.get());
+        } finally {
+            // Restore context classloader that was present before this
+            // test started, so that in case of a test failure we don't stuff
+            // up later tests...
+            Thread.currentThread().setContextClassLoader(origContextClassLoader);
+
+            // and restore all the standard converters
+            ConvertUtils.deregister();
+        }
+    }
+
+    /**
+     * Test whether registering a custom Converter subclass while
+     * a custom context classloader is set causes a memory leak.
+     *
+     * <p>This test emulates a j2ee container where BeanUtils has been
+     * loaded from a "common" lib location that is shared across all
+     * components running within the container. The "component" registers
+     * a converter object, whose class was loaded via the component-specific
+     * classloader. The registered converter:
+     * <ul>
+     * <li>should not be visible to other components; and</li>
+     * <li>should not prevent the component-specific classloader from being
+     *  garbage-collected when the container sets its reference to null.
+     * </ul>
+     *
+     */
+    @Test
+    public void testComponentRegistersCustomConverter() throws Exception {
+
+        final ClassLoader origContextClassLoader = Thread.currentThread().getContextClassLoader();
+        try {
+            // sanity check; who's paranoid?? :-)
+            assertEquals(origContextClassLoader, ConvertUtils.class.getClassLoader());
+
+            // create a custom classloader for a "component"
+            // just like a container would.
+            ClassReloader componentLoader = new ClassReloader(origContextClassLoader);
+
+            // Load a custom Converter via component loader. This emulates what
+            // would happen if a user wrote their own FloatConverter subclass
+            // and deployed it via the component-specific classpath.
+            Thread.currentThread().setContextClassLoader(componentLoader);
+            {
+              // Here we pretend we're running inside the component, and that
+              // a class FloatConverter has been loaded from the component's
+              // private classpath.
+              final Class<?> newFloatConverterClass = componentLoader.reload(FloatConverter.class);
+              Object newFloatConverter = newFloatConverterClass.newInstance();
+              assertTrue(newFloatConverter.getClass().getClassLoader() == componentLoader);
+
+              // verify that this new object does implement the Converter type
+              // despite being loaded via a classloader different from the one
+              // that loaded the Converter class.
+              assertTrue(
+                "Converter loader via child does not implement parent type",
+                Converter.class.isInstance(newFloatConverter));
+
+              // this converter registration will only apply to the
+              // componentLoader classloader...
+              ConvertUtils.register((Converter)newFloatConverter, Float.TYPE);
+
+              // After registering a custom converter, lookup should return
+              // it back to us. We'll try this lookup again with a different
+              // context-classloader set, and shouldn't see it
+              final Converter componentConverter = ConvertUtils.lookup(Float.TYPE);
+              assertTrue(componentConverter.getClass().getClassLoader() == componentLoader);
+
+              newFloatConverter = null;
+            }
+            Thread.currentThread().setContextClassLoader(origContextClassLoader);
+
+            // Because the context classloader has been reset, we shouldn't
+            // see the custom registered converter here...
+            final Converter sharedConverter = ConvertUtils.lookup(Float.TYPE);
+            assertFalse(sharedConverter.getClass().getClassLoader() == componentLoader);
+
+            // and here we should see it again
+            Thread.currentThread().setContextClassLoader(componentLoader);
+            {
+                final Converter componentConverter = ConvertUtils.lookup(Float.TYPE);
+                assertTrue(componentConverter.getClass().getClassLoader() == componentLoader);
+            }
+            Thread.currentThread().setContextClassLoader(origContextClassLoader);
+            // Emulate a container "undeploying" the component. This should
+            // make component loader available for garbage collection (we hope)
+            final WeakReference<ClassLoader> weakRefToComponent = new WeakReference<>(componentLoader);
+            componentLoader = null;
+
+            // force garbage collection and  verify that the componentLoader
+            // has been garbage-collected
+            forceGarbageCollection(weakRefToComponent);
+            assertNull(
+                "Component classloader did not release properly; memory leak present",
+                weakRefToComponent.get());
+        } finally {
+            // Restore context classloader that was present before this
+            // test started. It is expected to be the same as the system
+            // classloader, but we handle all cases here..
+            Thread.currentThread().setContextClassLoader(origContextClassLoader);
+
+            // and restore all the standard converters
+            ConvertUtils.deregister();
+        }
+    }
+
+    /**
+     * Attempt to force garbage collection of the specified target.
+     *
+     * <p>Unfortunately there is no way to force a JVM to perform
+     * garbage collection; all we can do is <i>hint</i> to it that
+     * garbage-collection would be a good idea, and to consume
+     * memory in order to trigger it.</p>
+     *
+     * <p>On return, target.get() will return null if the target has
+     * been garbage collected.</p>
+     *
+     * <p>If target.get() still returns non-null after this method has returned,
+     * then either there is some reference still being held to the target, or
+     * else we were not able to trigger garbage collection; there is no way
+     * to tell these scenarios apart.</p>
+     */
+    private void forceGarbageCollection(final WeakReference<?> target) {
+        int bytes = 2;
+
+        while(target.get() != null) {
+            System.gc();
+
+            // Create increasingly-large amounts of non-referenced memory
+            // in order to persuade the JVM to collect it. We are hoping
+            // here that the JVM is dumb enough to run a full gc pass over
+            // all data (including the target) rather than simply collecting
+            // this easily-reclaimable memory!
+            try {
+                @SuppressWarnings("unused")
+                final
+                byte[] b = new byte[bytes];
+                bytes = bytes * 2;
+            } catch(final OutOfMemoryError e) {
+                // well that sure should have forced a garbage collection
+                // run to occur!
+                break;
+            }
+        }
+
+        // and let's do one more just to clean up any garbage we might have
+        // created on the last pass..
+        System.gc();
+    }
+}
diff --git a/src/test/java/org/apache/commons/beanutils2/locale/LocaleBeanificationTestCase.java b/src/test/java/org/apache/commons/beanutils2/locale/LocaleBeanificationTestCase.java
index adfc844..cdc9a26 100644
--- a/src/test/java/org/apache/commons/beanutils2/locale/LocaleBeanificationTestCase.java
+++ b/src/test/java/org/apache/commons/beanutils2/locale/LocaleBeanificationTestCase.java
@@ -1,580 +1,580 @@
-/*
- * 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.commons.beanutils2.locale;
-
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.util.Locale;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.apache.commons.beanutils2.BeanUtilsBean;
-import org.apache.commons.beanutils2.BeanUtilsTestCase;
-import org.apache.commons.beanutils2.ContextClassLoaderLocal;
-import org.apache.commons.beanutils2.ConversionException;
-import org.apache.commons.beanutils2.ConvertUtils;
-import org.apache.commons.beanutils2.PrimitiveBean;
-import org.apache.commons.beanutils2.locale.converters.LongLocaleConverter;
-import org.apache.commons.logging.LogFactory;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * <p>
- * Test Case for changes made during LocaleBeanutils Beanification.
- * This is basically a cut-and-correct version of the beanutils beanifications tests.
- * </p>
- *
- */
-
-public class LocaleBeanificationTestCase extends TestCase {
-
-    // ---------------------------------------------------- Constants
-
-    /** Maximum number of iterations before our test fails */
-    public static final int MAX_GC_ITERATIONS = 50;
-
-    // ---------------------------------------------------- Instance Variables
-
-
-    // ---------------------------------------------------------- Constructors
-
-
-    /**
-     * Construct a new instance of this test case.
-     *
-     * @param name Name of the test case
-     */
-    public LocaleBeanificationTestCase(final String name) {
-        super(name);
-    }
-
-
-    // -------------------------------------------------- Overall Test Methods
-
-
-    /**
-     * Set up instance variables required by this test case.
-     */
-    @Override
-    public void setUp() {
-
-        LocaleConvertUtils.deregister();
-
-    }
-
-
-    /**
-     * Return the tests included in this test suite.
-     */
-    public static Test suite() {
-        return new TestSuite(LocaleBeanificationTestCase.class);
-    }
-
-
-    /**
-     * Tear down instance variables required by this test case.
-     */
-    @Override
-    public void tearDown() {
-        // No action required
-    }
-
-
-    // ------------------------------------------------ Individual Test Methods
-
-    /** Test of the methodology we'll use for some of the later tests */
-    public void testMemoryTestMethodology() throws Exception {
-        // test methodology
-        // many thanks to Juozas Baliuka for suggesting this method
-        ClassLoader loader = new ClassLoader(this.getClass().getClassLoader()) {};
-        final WeakReference<ClassLoader> reference = new  WeakReference<>(loader);
-        Class<?> myClass = loader.loadClass("org.apache.commons.beanutils2.BetaBean");
-
-        assertNotNull("Weak reference released early", reference.get());
-
-        // dereference class loader and class:
-        loader = null;
-        myClass = null;
-
-        int iterations = 0;
-        int bytz = 2;
-        while(true) {
-            System.gc();
-            if(iterations++ > MAX_GC_ITERATIONS){
-                fail("Max iterations reached before resource released.");
-            }
-            if( reference.get() == null ) {
-                break;
-
-            }
-            // create garbage:
-            final byte[] b =  new byte[bytz];
-            bytz = bytz * 2;
-        }
-    }
-
-    /** Tests whether classloaders and beans are released from memory by the map used by beanutils */
-    public void testMemoryLeak2() throws Exception {
-        // tests when the map used by beanutils has the right behaviour
-
-        if (BeanUtilsTestCase.isPre14JVM()) {
-            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
-            return;
-        }
-
-        // many thanks to Juozas Baliuka for suggesting this methodology
-        TestClassLoader loader = new TestClassLoader();
-        final ReferenceQueue<Object> queue = new ReferenceQueue<>();
-        final WeakReference<ClassLoader> loaderReference = new WeakReference<ClassLoader>(loader, queue);
-        Integer test = new Integer(1);
-
-        final WeakReference<Integer> testReference = new WeakReference<>(test, queue);
-        //Map map = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD, true);
-        final Map<TestClassLoader, Integer> map = new WeakHashMap<>();
-        map.put(loader, test);
-
-        assertEquals("In map", test, map.get(loader));
-        assertNotNull("Weak reference released early (1)", loaderReference.get());
-        assertNotNull("Weak reference released early (2)", testReference.get());
-
-        // dereference strong references
-        loader = null;
-        test = null;
-
-        int iterations = 0;
-        int bytz = 2;
-        while(true) {
-            System.gc();
-            if(iterations++ > MAX_GC_ITERATIONS){
-                fail("Max iterations reached before resource released.");
-            }
-            map.isEmpty();
-
-            if(
-                loaderReference.get() == null &&
-                testReference.get() == null) {
-                break;
-
-            }
-            // create garbage:
-            final byte[] b =  new byte[bytz];
-            bytz = bytz * 2;
-        }
-    }
-
-    /** Tests whether classloaders and beans are released from memory */
-    public void testMemoryLeak() throws Exception {
-        if (BeanUtilsTestCase.isPre14JVM()) {
-            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
-            return;
-        }
-
-        // many thanks to Juozas Baliuka for suggesting this methodology
-        TestClassLoader loader = new TestClassLoader();
-        final WeakReference<TestClassLoader> loaderReference = new  WeakReference<>(loader);
-        LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();
-
-        class GetBeanUtilsBeanThread extends Thread {
-
-            LocaleBeanUtilsBean beanUtils;
-            LocaleConvertUtilsBean convertUtils;
-
-            GetBeanUtilsBeanThread() {}
-
-            @Override
-            public void run() {
-                beanUtils = LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();
-                convertUtils = LocaleConvertUtilsBean.getInstance();
-                // XXX Log keeps a reference around!
-                LogFactory.releaseAll();
-            }
-
-            @Override
-            public String toString() {
-                return "GetBeanUtilsBeanThread";
-            }
-        }
-
-
-        GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread();
-        final WeakReference<GetBeanUtilsBeanThread> threadWeakReference = new WeakReference<>(thread);
-        thread.setContextClassLoader(loader);
-
-        thread.start();
-        thread.join();
-
-        final WeakReference<LocaleBeanUtilsBean> beanUtilsReference = new WeakReference<>(thread.beanUtils);
-        final WeakReference<LocaleConvertUtilsBean> convertUtilsReference = new WeakReference<>(thread.convertUtils);
-
-        assertNotNull("Weak reference released early (1)", loaderReference.get());
-        assertNotNull("Weak reference released early (2)", beanUtilsReference.get());
-        assertNotNull("Weak reference released early (4)", convertUtilsReference.get());
-
-        // dereference strong references
-        loader = null;
-        thread.setContextClassLoader(null);
-        thread = null;
-
-        int iterations = 0;
-        int bytz = 2;
-        while(true) {
-            LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();
-            System.gc();
-            if(iterations++ > MAX_GC_ITERATIONS){
-                fail("Max iterations reached before resource released.");
-            }
-
-            if(
-                loaderReference.get() == null &&
-                beanUtilsReference.get() == null &&
-                convertUtilsReference.get() == null) {
-                break;
-
-            }
-            // create garbage:
-            final byte[] b =  new byte[bytz];
-            bytz = bytz * 2;
-        }
-    }
-
-    /**
-     * Tests whether difference instances are loaded by different
-     * context classloaders.
-     */
-    public void testGetByContextClassLoader() throws Exception {
-
-        class GetBeanUtilsBeanThread extends Thread {
-
-            private final Signal signal;
-
-            GetBeanUtilsBeanThread(final Signal signal) {
-                this.signal = signal;
-            }
-
-            @Override
-            public void run() {
-                signal.setSignal(2);
-                signal.setBean(LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
-                signal.setConvertUtils(LocaleConvertUtilsBean.getInstance());
-            }
-
-            @Override
-            public String toString() {
-                return "GetBeanUtilsBeanThread";
-            }
-        }
-
-        final Signal signal = new Signal();
-        signal.setSignal(1);
-
-        final GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread(signal);
-        thread.setContextClassLoader(new TestClassLoader());
-
-        thread.start();
-        thread.join();
-
-        assertEquals("Signal not set by test thread", 2, signal.getSignal());
-        assertTrue(
-                    "Different LocaleBeanUtilsBean instances per context classloader",
-                    BeanUtilsBean.getInstance() != signal.getBean());
-        assertTrue(
-                    "Different LocaleConvertUtilsBean instances per context classloader",
-                    LocaleConvertUtilsBean.getInstance() != signal.getConvertUtils());
-    }
-
-
-    /**
-     * Tests whether difference instances are loaded by different
-     * context classloaders.
-     */
-    public void testContextClassLoaderLocal() throws Exception {
-
-        class CCLLTesterThread extends Thread {
-
-            private final Signal signal;
-            private final ContextClassLoaderLocal<Integer> ccll;
-
-            CCLLTesterThread(final Signal signal, final ContextClassLoaderLocal<Integer> ccll) {
-                this.signal = signal;
-                this.ccll = ccll;
-            }
-
-            @Override
-            public void run() {
-                ccll.set(new Integer(1789));
-                signal.setSignal(2);
-                signal.setMarkerObject(ccll.get());
-            }
-
-            @Override
-            public String toString() {
-                return "CCLLTesterThread";
-            }
-        }
-
-        final ContextClassLoaderLocal<Integer> ccll = new ContextClassLoaderLocal<>();
-        ccll.set(1776);
-        assertEquals("Start thread sets value", new Integer(1776), ccll.get());
-
-        final Signal signal = new Signal();
-        signal.setSignal(1);
-
-        final CCLLTesterThread thread = new CCLLTesterThread(signal, ccll);
-        thread.setContextClassLoader(new TestClassLoader());
-
-        thread.start();
-        thread.join();
-
-        assertEquals("Signal not set by test thread", 2, signal.getSignal());
-        assertEquals("Second thread preserves value", new Integer(1776), ccll.get());
-        assertEquals("Second thread gets value it set", new Integer(1789), signal.getMarkerObject());
-    }
-
-    /** Tests whether calls are independent for different classloaders */
-    public void testContextClassloaderIndependence() throws Exception {
-
-        class TestIndependenceThread extends Thread {
-            private final Signal signal;
-            private final PrimitiveBean bean;
-
-            TestIndependenceThread(final Signal signal, final PrimitiveBean bean) {
-                this.signal = signal;
-                this.bean = bean;
-            }
-
-            @Override
-            public void run() {
-                try {
-                    signal.setSignal(3);
-                    LocaleConvertUtils.register(new LocaleConverter() {
-                                            @Override
-                                            public <T> T convert(final Class<T> type, final Object value) {
-                                                return ConvertUtils.primitiveToWrapper(type).cast(9);
-                                            }
-                                            @Override
-                                            public <T> T convert(final Class<T> type, final Object value, final String pattern) {
-                                                return ConvertUtils.primitiveToWrapper(type).cast(9);
-                                            }
-                                                }, Integer.TYPE, Locale.getDefault());
-                    LocaleBeanUtils.setProperty(bean, "int", "1");
-                } catch (final Exception e) {
-                    e.printStackTrace();
-                    signal.setException(e);
-                }
-            }
-
-            @Override
-            public String toString() {
-                return "TestIndependenceThread";
-            }
-        }
-
-        final PrimitiveBean bean = new PrimitiveBean();
-        LocaleBeanUtils.setProperty(bean, "int", new Integer(1));
-        assertEquals("Wrong property value (1)", 1, bean.getInt());
-
-        LocaleConvertUtils.register(new LocaleConverter() {
-                                @Override
-                                public <T> T convert(final Class<T> type, final Object value) {
-                                    return ConvertUtils.primitiveToWrapper(type).cast(5);
-                                }
-                                @Override
-                                public <T> T convert(final Class<T> type, final Object value, final String pattern) {
-                                    return ConvertUtils.primitiveToWrapper(type).cast(5);
-                                }
-                                    }, Integer.TYPE, Locale.getDefault());
-        LocaleBeanUtils.setProperty(bean, "int", "1");
-        assertEquals("Wrong property value(2)", 5, bean.getInt());
-
-        final Signal signal = new Signal();
-        signal.setSignal(1);
-        final TestIndependenceThread thread = new TestIndependenceThread(signal, bean);
-        thread.setContextClassLoader(new TestClassLoader());
-
-        thread.start();
-        thread.join();
-
-        assertNull("Exception thrown by test thread:" + signal.getException(), signal.getException());
-        assertEquals("Signal not set by test thread", 3, signal.getSignal());
-        assertEquals("Wrong property value(3)", 9, bean.getInt());
-
-    }
-
-    /** Tests whether different threads can set beanutils instances correctly */
-    public void testBeanUtilsBeanSetInstance() throws Exception {
-
-        class SetInstanceTesterThread extends Thread {
-
-            private final Signal signal;
-            private final LocaleBeanUtilsBean bean;
-
-            SetInstanceTesterThread(final Signal signal, final LocaleBeanUtilsBean bean) {
-                this.signal = signal;
-                this.bean = bean;
-            }
-
-            @Override
-            public void run() {
-                LocaleBeanUtilsBean.setInstance(bean);
-                signal.setSignal(21);
-                signal.setBean(LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
-            }
-
-            @Override
-            public String toString() {
-                return "SetInstanceTesterThread";
-            }
-        }
-
-        final Signal signal = new Signal();
-        signal.setSignal(1);
-
-        final LocaleBeanUtilsBean beanOne = new LocaleBeanUtilsBean();
-        final LocaleBeanUtilsBean beanTwo = new LocaleBeanUtilsBean();
-
-        final SetInstanceTesterThread thread = new SetInstanceTesterThread(signal, beanTwo);
-        thread.setContextClassLoader(new TestClassLoader());
-
-        LocaleBeanUtilsBean.setInstance(beanOne);
-        assertEquals("Start thread gets right instance", beanOne, LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
-
-        thread.start();
-        thread.join();
-
-        assertEquals("Signal not set by test thread", 21, signal.getSignal());
-        assertEquals("Second thread preserves value", beanOne, LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
-        assertEquals("Second thread gets value it set", beanTwo, signal.getBean());
-    }
-
-    /** Tests whether the unset method works*/
-    public void testContextClassLoaderUnset() throws Exception {
-        final LocaleBeanUtilsBean beanOne = new LocaleBeanUtilsBean();
-        final ContextClassLoaderLocal<LocaleBeanUtilsBean> ccll = new ContextClassLoaderLocal<>();
-        ccll.set(beanOne);
-        assertEquals("Start thread gets right instance", beanOne, ccll.get());
-        ccll.unset();
-        assertTrue("Unset works", !beanOne.equals(ccll.get()));
-    }
-
-    /**
-     * Test registering a locale-aware converter with the standard ConvertUtils.
-     */
-    public void testLocaleAwareConverterInConvertUtils() throws Exception {
-        try {
-            // first use the default non-locale-aware converter
-            try {
-                final Long data = (Long) ConvertUtils.convert("777", Long.class);
-                assertEquals("Standard format long converted ok", 777, data.longValue());
-            }
-            catch(final ConversionException ex) {
-                fail("Unable to convert non-locale-aware number 777");
-            }
-
-            // now try default converter with special delimiters
-            try {
-                // This conversion will cause an error. But the default
-                // Long converter is set up to return a default value of
-                // zero on error.
-                final Long data = (Long) ConvertUtils.convert("1.000.000", Long.class);
-                assertEquals("Standard format behaved as expected", 0, data.longValue());
-            }
-            catch(final ConversionException ex) {
-                fail("Unexpected exception from standard Long converter.");
-            }
-
-            // Now try using a locale-aware converter together with
-            // locale-specific input string. Note that in the german locale,
-            // large numbers can be split up into groups of three digits
-            // using a dot character (and comma is the decimal-point indicator).
-            try {
-
-                final Locale germanLocale = Locale.GERMAN;
-                final LongLocaleConverter longLocaleConverter = new LongLocaleConverter(germanLocale);
-                ConvertUtils.register(longLocaleConverter, Long.class);
-
-                final Long data = (Long) ConvertUtils.convert("1.000.000", Long.class);
-                assertEquals("German-format long converted ok", 1000000, data.longValue());
-            } catch(final ConversionException ex) {
-                fail("Unable to convert german-format number");
-            }
-        } finally {
-            ConvertUtils.deregister();
-        }
-    }
-
-    // ---- Auxillary classes
-
-    class TestClassLoader extends ClassLoader {
-        @Override
-        public String toString() {
-            return "TestClassLoader";
-        }
-    }
-
-    class Signal {
-        private Exception e;
-        private int signal = 0;
-        private LocaleBeanUtilsBean bean;
-        private LocaleConvertUtilsBean convertUtils;
-        private Object marker;
-
-        public Exception getException() {
-            return e;
-        }
-
-        public void setException(final Exception e) {
-            this.e = e;
-        }
-
-        public int getSignal() {
-            return signal;
-        }
-
-        public void setSignal(final int signal) {
-            this.signal = signal;
-        }
-
-        public Object getMarkerObject() {
-            return marker;
-        }
-
-        public void setMarkerObject(final Object marker) {
-            this.marker = marker;
-        }
-
-        public LocaleBeanUtilsBean getBean() {
-            return bean;
-        }
-
-        public void setBean(final LocaleBeanUtilsBean bean) {
-            this.bean = bean;
-        }
-
-        public LocaleConvertUtilsBean getConvertUtils() {
-            return convertUtils;
-        }
-
-        public void setConvertUtils(final LocaleConvertUtilsBean convertUtils) {
-            this.convertUtils = convertUtils;
-        }
-    }
-}
-
+/*
+ * 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.commons.beanutils2.locale;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Locale;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.apache.commons.beanutils2.BeanUtilsBean;
+import org.apache.commons.beanutils2.BeanUtilsTestCase;
+import org.apache.commons.beanutils2.ContextClassLoaderLocal;
+import org.apache.commons.beanutils2.ConversionException;
+import org.apache.commons.beanutils2.ConvertUtils;
+import org.apache.commons.beanutils2.PrimitiveBean;
+import org.apache.commons.beanutils2.locale.converters.LongLocaleConverter;
+import org.apache.commons.logging.LogFactory;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ * Test Case for changes made during LocaleBeanutils Beanification.
+ * This is basically a cut-and-correct version of the beanutils beanifications tests.
+ * </p>
+ *
+ */
+
+public class LocaleBeanificationTestCase extends TestCase {
+
+    // ---------------------------------------------------- Constants
+
+    /** Maximum number of iterations before our test fails */
+    public static final int MAX_GC_ITERATIONS = 50;
+
+    // ---------------------------------------------------- Instance Variables
+
+
+    // ---------------------------------------------------------- Constructors
+
+
+    /**
+     * Construct a new instance of this test case.
+     *
+     * @param name Name of the test case
+     */
+    public LocaleBeanificationTestCase(final String name) {
+        super(name);
+    }
+
+
+    // -------------------------------------------------- Overall Test Methods
+
+
+    /**
+     * Set up instance variables required by this test case.
+     */
+    @Override
+    public void setUp() {
+
+        LocaleConvertUtils.deregister();
+
+    }
+
+
+    /**
+     * Return the tests included in this test suite.
+     */
+    public static Test suite() {
+        return new TestSuite(LocaleBeanificationTestCase.class);
+    }
+
+
+    /**
+     * Tear down instance variables required by this test case.
+     */
+    @Override
+    public void tearDown() {
+        // No action required
+    }
+
+
+    // ------------------------------------------------ Individual Test Methods
+
+    /** Test of the methodology we'll use for some of the later tests */
+    public void testMemoryTestMethodology() throws Exception {
+        // test methodology
+        // many thanks to Juozas Baliuka for suggesting this method
+        ClassLoader loader = new ClassLoader(this.getClass().getClassLoader()) {};
+        final WeakReference<ClassLoader> reference = new  WeakReference<>(loader);
+        Class<?> myClass = loader.loadClass("org.apache.commons.beanutils2.BetaBean");
+
+        assertNotNull("Weak reference released early", reference.get());
+
+        // dereference class loader and class:
+        loader = null;
+        myClass = null;
+
+        int iterations = 0;
+        int bytz = 2;
+        while(true) {
+            System.gc();
+            if(iterations++ > MAX_GC_ITERATIONS){
+                fail("Max iterations reached before resource released.");
+            }
+            if( reference.get() == null ) {
+                break;
+
+            }
+            // create garbage:
+            final byte[] b =  new byte[bytz];
+            bytz = bytz * 2;
+        }
+    }
+
+    /** Tests whether classloaders and beans are released from memory by the map used by beanutils */
+    public void testMemoryLeak2() throws Exception {
+        // tests when the map used by beanutils has the right behaviour
+
+        if (BeanUtilsTestCase.isPre14JVM()) {
+            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
+            return;
+        }
+
+        // many thanks to Juozas Baliuka for suggesting this methodology
+        TestClassLoader loader = new TestClassLoader();
+        final ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        final WeakReference<ClassLoader> loaderReference = new WeakReference<>(loader, queue);
+        Integer test = new Integer(1);
+
+        final WeakReference<Integer> testReference = new WeakReference<>(test, queue);
+        //Map map = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD, true);
+        final Map<TestClassLoader, Integer> map = new WeakHashMap<>();
+        map.put(loader, test);
+
+        assertEquals("In map", test, map.get(loader));
+        assertNotNull("Weak reference released early (1)", loaderReference.get());
+        assertNotNull("Weak reference released early (2)", testReference.get());
+
+        // dereference strong references
+        loader = null;
+        test = null;
+
+        int iterations = 0;
+        int bytz = 2;
+        while(true) {
+            System.gc();
+            if(iterations++ > MAX_GC_ITERATIONS){
+                fail("Max iterations reached before resource released.");
+            }
+            map.isEmpty();
+
+            if(
+                loaderReference.get() == null &&
+                testReference.get() == null) {
+                break;
+
+            }
+            // create garbage:
+            final byte[] b =  new byte[bytz];
+            bytz = bytz * 2;
+        }
+    }
+
+    /** Tests whether classloaders and beans are released from memory */
+    public void testMemoryLeak() throws Exception {
+        if (BeanUtilsTestCase.isPre14JVM()) {
+            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
+            return;
+        }
+
+        // many thanks to Juozas Baliuka for suggesting this methodology
+        TestClassLoader loader = new TestClassLoader();
+        final WeakReference<TestClassLoader> loaderReference = new  WeakReference<>(loader);
+        LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();
+
+        class GetBeanUtilsBeanThread extends Thread {
+
+            LocaleBeanUtilsBean beanUtils;
+            LocaleConvertUtilsBean convertUtils;
+
+            GetBeanUtilsBeanThread() {}
+
+            @Override
+            public void run() {
+                beanUtils = LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();
+                convertUtils = LocaleConvertUtilsBean.getInstance();
+                // XXX Log keeps a reference around!
+                LogFactory.releaseAll();
+            }
+
+            @Override
+            public String toString() {
+                return "GetBeanUtilsBeanThread";
+            }
+        }
+
+
+        GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread();
+        final WeakReference<GetBeanUtilsBeanThread> threadWeakReference = new WeakReference<>(thread);
+        thread.setContextClassLoader(loader);
+
+        thread.start();
+        thread.join();
+
+        final WeakReference<LocaleBeanUtilsBean> beanUtilsReference = new WeakReference<>(thread.beanUtils);
+        final WeakReference<LocaleConvertUtilsBean> convertUtilsReference = new WeakReference<>(thread.convertUtils);
+
+        assertNotNull("Weak reference released early (1)", loaderReference.get());
+        assertNotNull("Weak reference released early (2)", beanUtilsReference.get());
+        assertNotNull("Weak reference released early (4)", convertUtilsReference.get());
+
+        // dereference strong references
+        loader = null;
+        thread.setContextClassLoader(null);
+        thread = null;
+
+        int iterations = 0;
+        int bytz = 2;
+        while(true) {
+            LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();
+            System.gc();
+            if(iterations++ > MAX_GC_ITERATIONS){
+                fail("Max iterations reached before resource released.");
+            }
+
+            if(
+                loaderReference.get() == null &&
+                beanUtilsReference.get() == null &&
+                convertUtilsReference.get() == null) {
+                break;
+
+            }
+            // create garbage:
+            final byte[] b =  new byte[bytz];
+            bytz = bytz * 2;
+        }
+    }
+
+    /**
+     * Tests whether difference instances are loaded by different
+     * context classloaders.
+     */
+    public void testGetByContextClassLoader() throws Exception {
+
+        class GetBeanUtilsBeanThread extends Thread {
+
+            private final Signal signal;
+
+            GetBeanUtilsBeanThread(final Signal signal) {
+                this.signal = signal;
+            }
+
+            @Override
+            public void run() {
+                signal.setSignal(2);
+                signal.setBean(LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
+                signal.setConvertUtils(LocaleConvertUtilsBean.getInstance());
+            }
+
+            @Override
+            public String toString() {
+                return "GetBeanUtilsBeanThread";
+            }
+        }
+
+        final Signal signal = new Signal();
+        signal.setSignal(1);
+
+        final GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread(signal);
+        thread.setContextClassLoader(new TestClassLoader());
+
+        thread.start();
+        thread.join();
+
+        assertEquals("Signal not set by test thread", 2, signal.getSignal());
+        assertTrue(
+                    "Different LocaleBeanUtilsBean instances per context classloader",
+                    BeanUtilsBean.getInstance() != signal.getBean());
+        assertTrue(
+                    "Different LocaleConvertUtilsBean instances per context classloader",
+                    LocaleConvertUtilsBean.getInstance() != signal.getConvertUtils());
+    }
+
+
+    /**
+     * Tests whether difference instances are loaded by different
+     * context classloaders.
+     */
+    public void testContextClassLoaderLocal() throws Exception {
+
+        class CCLLTesterThread extends Thread {
+
+            private final Signal signal;
+            private final ContextClassLoaderLocal<Integer> ccll;
+
+            CCLLTesterThread(final Signal signal, final ContextClassLoaderLocal<Integer> ccll) {
+                this.signal = signal;
+                this.ccll = ccll;
+            }
+
+            @Override
+            public void run() {
+                ccll.set(new Integer(1789));
+                signal.setSignal(2);
+                signal.setMarkerObject(ccll.get());
+            }
+
+            @Override
+            public String toString() {
+                return "CCLLTesterThread";
+            }
+        }
+
+        final ContextClassLoaderLocal<Integer> ccll = new ContextClassLoaderLocal<>();
+        ccll.set(1776);
+        assertEquals("Start thread sets value", new Integer(1776), ccll.get());
+
+        final Signal signal = new Signal();
+        signal.setSignal(1);
+
+        final CCLLTesterThread thread = new CCLLTesterThread(signal, ccll);
+        thread.setContextClassLoader(new TestClassLoader());
+
+        thread.start();
+        thread.join();
+
+        assertEquals("Signal not set by test thread", 2, signal.getSignal());
+        assertEquals("Second thread preserves value", new Integer(1776), ccll.get());
+        assertEquals("Second thread gets value it set", new Integer(1789), signal.getMarkerObject());
+    }
+
+    /** Tests whether calls are independent for different classloaders */
+    public void testContextClassloaderIndependence() throws Exception {
+
+        class TestIndependenceThread extends Thread {
+            private final Signal signal;
+            private final PrimitiveBean bean;
+
+            TestIndependenceThread(final Signal signal, final PrimitiveBean bean) {
+                this.signal = signal;
+                this.bean = bean;
+            }
+
+            @Override
+            public void run() {
+                try {
+                    signal.setSignal(3);
+                    LocaleConvertUtils.register(new LocaleConverter() {
+                                            @Override
+                                            public <T> T convert(final Class<T> type, final Object value) {
+                                                return ConvertUtils.primitiveToWrapper(type).cast(9);
+                                            }
+                                            @Override
+                                            public <T> T convert(final Class<T> type, final Object value, final String pattern) {
+                                                return ConvertUtils.primitiveToWrapper(type).cast(9);
+                                            }
+                                                }, Integer.TYPE, Locale.getDefault());
+                    LocaleBeanUtils.setProperty(bean, "int", "1");
+                } catch (final Exception e) {
+                    e.printStackTrace();
+                    signal.setException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "TestIndependenceThread";
+            }
+        }
+
+        final PrimitiveBean bean = new PrimitiveBean();
+        LocaleBeanUtils.setProperty(bean, "int", new Integer(1));
+        assertEquals("Wrong property value (1)", 1, bean.getInt());
+
+        LocaleConvertUtils.register(new LocaleConverter() {
+                                @Override
+                                public <T> T convert(final Class<T> type, final Object value) {
+                                    return ConvertUtils.primitiveToWrapper(type).cast(5);
+                                }
+                                @Override
+                                public <T> T convert(final Class<T> type, final Object value, final String pattern) {
+                                    return ConvertUtils.primitiveToWrapper(type).cast(5);
+                                }
+                                    }, Integer.TYPE, Locale.getDefault());
+        LocaleBeanUtils.setProperty(bean, "int", "1");
+        assertEquals("Wrong property value(2)", 5, bean.getInt());
+
+        final Signal signal = new Signal();
+        signal.setSignal(1);
+        final TestIndependenceThread thread = new TestIndependenceThread(signal, bean);
+        thread.setContextClassLoader(new TestClassLoader());
+
+        thread.start();
+        thread.join();
+
+        assertNull("Exception thrown by test thread:" + signal.getException(), signal.getException());
+        assertEquals("Signal not set by test thread", 3, signal.getSignal());
+        assertEquals("Wrong property value(3)", 9, bean.getInt());
+
+    }
+
+    /** Tests whether different threads can set beanutils instances correctly */
+    public void testBeanUtilsBeanSetInstance() throws Exception {
+
+        class SetInstanceTesterThread extends Thread {
+
+            private final Signal signal;
+            private final LocaleBeanUtilsBean bean;
+
+            SetInstanceTesterThread(final Signal signal, final LocaleBeanUtilsBean bean) {
+                this.signal = signal;
+                this.bean = bean;
+            }
+
+            @Override
+            public void run() {
+                LocaleBeanUtilsBean.setInstance(bean);
+                signal.setSignal(21);
+                signal.setBean(LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
+            }
+
+            @Override
+            public String toString() {
+                return "SetInstanceTesterThread";
+            }
+        }
+
+        final Signal signal = new Signal();
+        signal.setSignal(1);
+
+        final LocaleBeanUtilsBean beanOne = new LocaleBeanUtilsBean();
+        final LocaleBeanUtilsBean beanTwo = new LocaleBeanUtilsBean();
+
+        final SetInstanceTesterThread thread = new SetInstanceTesterThread(signal, beanTwo);
+        thread.setContextClassLoader(new TestClassLoader());
+
+        LocaleBeanUtilsBean.setInstance(beanOne);
+        assertEquals("Start thread gets right instance", beanOne, LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
+
+        thread.start();
+        thread.join();
+
+        assertEquals("Signal not set by test thread", 21, signal.getSignal());
+        assertEquals("Second thread preserves value", beanOne, LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
+        assertEquals("Second thread gets value it set", beanTwo, signal.getBean());
+    }
+
+    /** Tests whether the unset method works*/
+    public void testContextClassLoaderUnset() throws Exception {
+        final LocaleBeanUtilsBean beanOne = new LocaleBeanUtilsBean();
+        final ContextClassLoaderLocal<LocaleBeanUtilsBean> ccll = new ContextClassLoaderLocal<>();
+        ccll.set(beanOne);
+        assertEquals("Start thread gets right instance", beanOne, ccll.get());
+        ccll.unset();
+        assertTrue("Unset works", !beanOne.equals(ccll.get()));
+    }
+
+    /**
+     * Test registering a locale-aware converter with the standard ConvertUtils.
+     */
+    public void testLocaleAwareConverterInConvertUtils() throws Exception {
+        try {
+            // first use the default non-locale-aware converter
+            try {
+                final Long data = (Long) ConvertUtils.convert("777", Long.class);
+                assertEquals("Standard format long converted ok", 777, data.longValue());
+            }
+            catch(final ConversionException ex) {
+                fail("Unable to convert non-locale-aware number 777");
+            }
+
+            // now try default converter with special delimiters
+            try {
+                // This conversion will cause an error. But the default
+                // Long converter is set up to return a default value of
+                // zero on error.
+                final Long data = (Long) ConvertUtils.convert("1.000.000", Long.class);
+                assertEquals("Standard format behaved as expected", 0, data.longValue());
+            }
+            catch(final ConversionException ex) {
+                fail("Unexpected exception from standard Long converter.");
+            }
+
+            // Now try using a locale-aware converter together with
+            // locale-specific input string. Note that in the german locale,
+            // large numbers can be split up into groups of three digits
+            // using a dot character (and comma is the decimal-point indicator).
+            try {
+
+                final Locale germanLocale = Locale.GERMAN;
+                final LongLocaleConverter longLocaleConverter = new LongLocaleConverter(germanLocale);
+                ConvertUtils.register(longLocaleConverter, Long.class);
+
+                final Long data = (Long) ConvertUtils.convert("1.000.000", Long.class);
+                assertEquals("German-format long converted ok", 1000000, data.longValue());
+            } catch(final ConversionException ex) {
+                fail("Unable to convert german-format number");
+            }
+        } finally {
+            ConvertUtils.deregister();
+        }
+    }
+
+    // ---- Auxillary classes
+
+    class TestClassLoader extends ClassLoader {
+        @Override
+        public String toString() {
+            return "TestClassLoader";
+        }
+    }
+
+    class Signal {
+        private Exception e;
+        private int signal = 0;
+        private LocaleBeanUtilsBean bean;
+        private LocaleConvertUtilsBean convertUtils;
+        private Object marker;
+
+        public Exception getException() {
+            return e;
+        }
+
+        public void setException(final Exception e) {
+            this.e = e;
+        }
+
+        public int getSignal() {
+            return signal;
+        }
+
+        public void setSignal(final int signal) {
+            this.signal = signal;
+        }
+
+        public Object getMarkerObject() {
+            return marker;
+        }
+
+        public void setMarkerObject(final Object marker) {
+            this.marker = marker;
+        }
+
+        public LocaleBeanUtilsBean getBean() {
+            return bean;
+        }
+
+        public void setBean(final LocaleBeanUtilsBean bean) {
+            this.bean = bean;
+        }
+
+        public LocaleConvertUtilsBean getConvertUtils() {
+            return convertUtils;
+        }
+
+        public void setConvertUtils(final LocaleConvertUtilsBean convertUtils) {
+            this.convertUtils = convertUtils;
+        }
+    }
+}
+
