You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/10/21 14:02:22 UTC

[commons-beanutils] branch master updated (7c58504 -> 483cb3c)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git.


    from 7c58504  Javadoc.
     new 69333b5  Remove trailing white spaces.
     new c603d87  Use final.
     new 5938fba  Use lambdas.
     new 40170f2  Revert "Use lambdas."
     new 483cb3c  Use diamonds.

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../beanutils2/BaseDynaBeanMapDecorator.java       |   14 +-
 .../org/apache/commons/beanutils2/BeanMap.java     |    4 +-
 .../apache/commons/beanutils2/BeanPredicate.java   |    2 +-
 .../beanutils2/BeanToPropertyValueTransformer.java |    2 +-
 .../beanutils2/MappedPropertyDescriptor.java       | 1058 +++++++++---------
 .../apache/commons/beanutils2/WrapDynaClass.java   |    2 +-
 .../apache/commons/beanutils2/package-info.java    |    2 +-
 .../commons/beanutils2/BeanPredicateTestCase.java  |    8 +-
 .../commons/beanutils2/BeanificationTestCase.java  | 1088 +++++++++---------
 .../commons/beanutils2/bugs/Jira157TestCase.java   |    2 +-
 .../commons/beanutils2/bugs/Jira520TestCase.java   |    2 +-
 .../beanutils2/converters/MemoryTestCase.java      |  582 +++++-----
 .../locale/LocaleBeanificationTestCase.java        | 1160 ++++++++++----------
 13 files changed, 1963 insertions(+), 1963 deletions(-)


[commons-beanutils] 01/05: Remove trailing white spaces.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git

commit 69333b5da88b1803ddebe119eeeb66a3f665cf42
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Oct 21 09:58:21 2019 -0400

    Remove trailing white spaces.
---
 .../commons/beanutils2/BaseDynaBeanMapDecorator.java       | 14 +++++++-------
 src/main/java/org/apache/commons/beanutils2/BeanMap.java   |  4 ++--
 .../commons/beanutils2/BeanToPropertyValueTransformer.java |  2 +-
 .../java/org/apache/commons/beanutils2/package-info.java   |  2 +-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/main/java/org/apache/commons/beanutils2/BaseDynaBeanMapDecorator.java b/src/main/java/org/apache/commons/beanutils2/BaseDynaBeanMapDecorator.java
index 9504501..da7f8bc 100644
--- a/src/main/java/org/apache/commons/beanutils2/BaseDynaBeanMapDecorator.java
+++ b/src/main/java/org/apache/commons/beanutils2/BaseDynaBeanMapDecorator.java
@@ -358,15 +358,15 @@ public abstract class BaseDynaBeanMapDecorator<K> implements Map<K, Object> {
      * Map.Entry implementation.
      */
     private static class MapEntry<K> implements Map.Entry<K, Object> {
-        
+
         private final K key;
         private final Object value;
-        
+
         MapEntry(final K key, final Object value) {
             this.key = key;
             this.value = value;
         }
-        
+
         @Override
         public boolean equals(final Object o) {
             if (!(o instanceof Map.Entry)) {
@@ -377,22 +377,22 @@ public abstract class BaseDynaBeanMapDecorator<K> implements Map<K, Object> {
                     (value == null ? e.getValue() == null
                                    : value.equals(e.getValue()));
         }
-        
+
         @Override
         public int hashCode() {
             return key.hashCode() + (value == null ? 0 : value.hashCode());
         }
-        
+
         @Override
         public K getKey() {
             return key;
         }
-        
+
         @Override
         public Object getValue() {
             return value;
         }
-        
+
         @Override
         public Object setValue(final Object value) {
             throw new UnsupportedOperationException();
diff --git a/src/main/java/org/apache/commons/beanutils2/BeanMap.java b/src/main/java/org/apache/commons/beanutils2/BeanMap.java
index 337fa96..b7b5e3a 100644
--- a/src/main/java/org/apache/commons/beanutils2/BeanMap.java
+++ b/src/main/java/org/apache/commons/beanutils2/BeanMap.java
@@ -101,7 +101,7 @@ public class BeanMap extends AbstractMap<String, Object> implements Cloneable {
 
     /**
      * Renders a string representation of this object.
-     * 
+     *
      * @return a <code>String</code> representation of this object
      */
     @Override
@@ -594,7 +594,7 @@ public class BeanMap extends AbstractMap<String, Object> implements Cloneable {
      * Map entry used by {@link BeanMap}.
      */
     protected static class Entry extends AbstractMap.SimpleEntry<String, Object> {
-        
+
         private static final long serialVersionUID = 1L;
         private final BeanMap owner;
 
diff --git a/src/main/java/org/apache/commons/beanutils2/BeanToPropertyValueTransformer.java b/src/main/java/org/apache/commons/beanutils2/BeanToPropertyValueTransformer.java
index 69b4bea..1401dcc 100644
--- a/src/main/java/org/apache/commons/beanutils2/BeanToPropertyValueTransformer.java
+++ b/src/main/java/org/apache/commons/beanutils2/BeanToPropertyValueTransformer.java
@@ -67,7 +67,7 @@ import org.apache.commons.logging.LogFactory;
  *
  * @param <T> the type of the input to the function
  * @param <R> the type of the result of the function
- * 
+ *
  * @see org.apache.commons.beanutils2.PropertyUtils
  * @see java.util.function.Function
  */
diff --git a/src/main/java/org/apache/commons/beanutils2/package-info.java b/src/main/java/org/apache/commons/beanutils2/package-info.java
index 38e5bb5..7041bd8 100644
--- a/src/main/java/org/apache/commons/beanutils2/package-info.java
+++ b/src/main/java/org/apache/commons/beanutils2/package-info.java
@@ -1017,7 +1017,7 @@
  * <h2>How Do I Set The BeanComparator Order To Be Ascending/Descending?</h2>
  * <p>
  * BeanComparator relies on an internal Comparator to perform the actual
- * comparisions. By default, a natural ordering comparator 
+ * comparisions. By default, a natural ordering comparator
  * is used which imposes a natural order. If you want to change the order,
  * then a custom Comparator should be created and passed into the
  * appropriate constructor.


[commons-beanutils] 05/05: Use diamonds.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git

commit 483cb3ce5d9dc88e4f3260118ef32685b68f5aba
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Oct 21 10:02:18 2019 -0400

    Use diamonds.
---
 .../beanutils2/MappedPropertyDescriptor.java       | 1058 +++++++++---------
 .../apache/commons/beanutils2/WrapDynaClass.java   |    2 +-
 .../commons/beanutils2/BeanificationTestCase.java  | 1088 +++++++++---------
 .../beanutils2/converters/MemoryTestCase.java      |  582 +++++-----
 .../locale/LocaleBeanificationTestCase.java        | 1160 ++++++++++----------
 5 files changed, 1945 insertions(+), 1945 deletions(-)

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 @@ public class WrapDynaClass implements DynaClass {
      */
     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;
+        }
+    }
+}
+


[commons-beanutils] 03/05: Use lambdas.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git

commit 5938fba9c0fa4420fe365295bbea8384a191e634
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Oct 21 09:59:27 2019 -0400

    Use lambdas.
---
 .../apache/commons/beanutils2/ConvertUtilsTestCase.java  | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/src/test/java/org/apache/commons/beanutils2/ConvertUtilsTestCase.java b/src/test/java/org/apache/commons/beanutils2/ConvertUtilsTestCase.java
index f5ae83c..52ec7e9 100644
--- a/src/test/java/org/apache/commons/beanutils2/ConvertUtilsTestCase.java
+++ b/src/test/java/org/apache/commons/beanutils2/ConvertUtilsTestCase.java
@@ -618,19 +618,9 @@ public class ConvertUtilsTestCase extends TestCase {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     // We need to use raw types in order to test legacy converters
     public void testConvertToString() throws Exception {
-        final Converter dummyConverter = new Converter() {
-            @Override
-            public Object convert(final Class type, final Object value) {
-                return value;
-            }
-        };
-
-        final Converter fooConverter = new Converter() {
-            @Override
-            public Object convert(final Class type, final Object value) {
-                return "Foo-Converter";
-            }
-        };
+        final Converter dummyConverter = (type, value) -> value;
+
+        final Converter fooConverter = (type, value) -> "Foo-Converter";
 
         final DateConverter dateConverter = new DateConverter();
         dateConverter.setLocale(Locale.US);


[commons-beanutils] 02/05: Use final.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git

commit c603d875db8dd09bde378aab458ae14eca8a956c
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Oct 21 09:58:57 2019 -0400

    Use final.
---
 src/main/java/org/apache/commons/beanutils2/BeanPredicate.java    | 2 +-
 .../java/org/apache/commons/beanutils2/BeanPredicateTestCase.java | 8 ++++----
 .../java/org/apache/commons/beanutils2/bugs/Jira157TestCase.java  | 2 +-
 .../java/org/apache/commons/beanutils2/bugs/Jira520TestCase.java  | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/main/java/org/apache/commons/beanutils2/BeanPredicate.java b/src/main/java/org/apache/commons/beanutils2/BeanPredicate.java
index 6be8d12..e894b5b 100644
--- a/src/main/java/org/apache/commons/beanutils2/BeanPredicate.java
+++ b/src/main/java/org/apache/commons/beanutils2/BeanPredicate.java
@@ -61,7 +61,7 @@ public class BeanPredicate<T> implements Predicate<T> {
      * @throws IllegalArgumentException when the property cannot be evaluated
      */
     @Override
-    public boolean test(Object object) {
+    public boolean test(final Object object) {
         boolean evaluation = false;
 
         try {
diff --git a/src/test/java/org/apache/commons/beanutils2/BeanPredicateTestCase.java b/src/test/java/org/apache/commons/beanutils2/BeanPredicateTestCase.java
index 0972174..bba384f 100644
--- a/src/test/java/org/apache/commons/beanutils2/BeanPredicateTestCase.java
+++ b/src/test/java/org/apache/commons/beanutils2/BeanPredicateTestCase.java
@@ -32,28 +32,28 @@ public class BeanPredicateTestCase extends TestCase {
     }
 
     public void testEqual() {
-        Predicate<String> p = (s) -> s.equals("foo");
+        final Predicate<String> p = (s) -> s.equals("foo");
         final BeanPredicate<String> predicate = new BeanPredicate<>("stringProperty", p);
         assertTrue(predicate.test(new TestBean("foo")));
         assertTrue(!predicate.test(new TestBean("bar")));
     }
 
     public void testNotEqual() {
-        Predicate<String> p = (s) -> !s.equals("foo");
+        final Predicate<String> p = (s) -> !s.equals("foo");
         final BeanPredicate<String> predicate = new BeanPredicate<>("stringProperty", p);
         assertTrue(!predicate.test(new TestBean("foo")));
         assertTrue(predicate.test(new TestBean("bar")));
     }
 
     public void testInstanceOf() {
-        Predicate<String> p = (s) -> (s instanceof String);
+        final Predicate<String> p = (s) -> (s instanceof String);
         final BeanPredicate<String> predicate = new BeanPredicate<>("stringProperty", p);
         assertTrue(predicate.test(new TestBean("foo")));
         assertTrue(predicate.test(new TestBean("bar")));
     }
 
     public void testNull() {
-        Predicate<String> p = (s) -> s == null;
+        final Predicate<String> p = (s) -> s == null;
         final BeanPredicate<String> predicate = new BeanPredicate<>("stringProperty", p);
         final String nullString = null;
         assertTrue(predicate.test(new TestBean(nullString)));
diff --git a/src/test/java/org/apache/commons/beanutils2/bugs/Jira157TestCase.java b/src/test/java/org/apache/commons/beanutils2/bugs/Jira157TestCase.java
index 81875e5..f100a2a 100644
--- a/src/test/java/org/apache/commons/beanutils2/bugs/Jira157TestCase.java
+++ b/src/test/java/org/apache/commons/beanutils2/bugs/Jira157TestCase.java
@@ -77,7 +77,7 @@ public class Jira157TestCase extends TestCase {
     protected void setUp() throws Exception {
         super.setUp();
 
-        BeanUtilsBean custom = new BeanUtilsBean();
+        final BeanUtilsBean custom = new BeanUtilsBean();
     	custom.getPropertyUtils().removeBeanIntrospector(SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS);
     	BeanUtilsBean.setInstance(custom);
     }
diff --git a/src/test/java/org/apache/commons/beanutils2/bugs/Jira520TestCase.java b/src/test/java/org/apache/commons/beanutils2/bugs/Jira520TestCase.java
index a440912..e3bec4f 100644
--- a/src/test/java/org/apache/commons/beanutils2/bugs/Jira520TestCase.java
+++ b/src/test/java/org/apache/commons/beanutils2/bugs/Jira520TestCase.java
@@ -49,7 +49,7 @@ public class Jira520TestCase extends TestCase {
         final BeanUtilsBean bub = new BeanUtilsBean();
         bub.getPropertyUtils().removeBeanIntrospector(SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS);
         final AlphaBean bean = new AlphaBean();
-        String result = bub.getProperty(bean, "class");
+        final String result = bub.getProperty(bean, "class");
         assertEquals("Class property should have been accessed", "class org.apache.commons.beanutils2.AlphaBean", result);
     }
 }


[commons-beanutils] 04/05: Revert "Use lambdas."

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git

commit 40170f2985e85ab772b6123e0c39fab8b3a4f02d
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Oct 21 10:00:24 2019 -0400

    Revert "Use lambdas."
    
    This reverts commit 5938fba9c0fa4420fe365295bbea8384a191e634.
---
 .../apache/commons/beanutils2/ConvertUtilsTestCase.java  | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/test/java/org/apache/commons/beanutils2/ConvertUtilsTestCase.java b/src/test/java/org/apache/commons/beanutils2/ConvertUtilsTestCase.java
index 52ec7e9..f5ae83c 100644
--- a/src/test/java/org/apache/commons/beanutils2/ConvertUtilsTestCase.java
+++ b/src/test/java/org/apache/commons/beanutils2/ConvertUtilsTestCase.java
@@ -618,9 +618,19 @@ public class ConvertUtilsTestCase extends TestCase {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     // We need to use raw types in order to test legacy converters
     public void testConvertToString() throws Exception {
-        final Converter dummyConverter = (type, value) -> value;
-
-        final Converter fooConverter = (type, value) -> "Foo-Converter";
+        final Converter dummyConverter = new Converter() {
+            @Override
+            public Object convert(final Class type, final Object value) {
+                return value;
+            }
+        };
+
+        final Converter fooConverter = new Converter() {
+            @Override
+            public Object convert(final Class type, final Object value) {
+                return "Foo-Converter";
+            }
+        };
 
         final DateConverter dateConverter = new DateConverter();
         dateConverter.setLocale(Locale.US);