Eol style

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/proxy/trunk@1582563 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/cglib/src/main/java/org/apache/commons/proxy2/cglib/CglibProxyFactory.java b/cglib/src/main/java/org/apache/commons/proxy2/cglib/CglibProxyFactory.java
index 05bca9f..5e74368 100644
--- a/cglib/src/main/java/org/apache/commons/proxy2/cglib/CglibProxyFactory.java
+++ b/cglib/src/main/java/org/apache/commons/proxy2/cglib/CglibProxyFactory.java
@@ -1,258 +1,258 @@
-/*

- * 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.proxy2.cglib;

-

-import java.io.Serializable;

-import java.lang.reflect.Method;

-

-import net.sf.cglib.proxy.Callback;

-import net.sf.cglib.proxy.CallbackFilter;

-import net.sf.cglib.proxy.Dispatcher;

-import net.sf.cglib.proxy.Enhancer;

-import net.sf.cglib.proxy.MethodInterceptor;

-import net.sf.cglib.proxy.MethodProxy;

-

-import org.apache.commons.lang3.ArrayUtils;

-import org.apache.commons.lang3.ObjectUtils;

-import org.apache.commons.proxy2.Interceptor;

-import org.apache.commons.proxy2.Invocation;

-import org.apache.commons.proxy2.Invoker;

-import org.apache.commons.proxy2.ObjectProvider;

-import org.apache.commons.proxy2.ProxyUtils;

-import org.apache.commons.proxy2.impl.AbstractSubclassingProxyFactory;

-

-/**

- * Cglib-based {@link org.apache.commons.proxy2.ProxyFactory ProxyFactory} implementation.

- */

-public class CglibProxyFactory extends AbstractSubclassingProxyFactory

-{

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private static final CallbackFilter CALLBACKFILTER = new CglibProxyFactoryCallbackFilter();

-

-    //******************************************************************************************************************

-    // ProxyFactory Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> targetProvider,

-            Class<?>... proxyClasses)

-    {

-        final Enhancer enhancer = new Enhancer();

-        enhancer.setClassLoader(classLoader);

-        enhancer.setInterfaces(toInterfaces(proxyClasses));

-        enhancer.setSuperclass(getSuperclass(proxyClasses));

-        enhancer.setCallbackFilter(CALLBACKFILTER);

-        enhancer.setCallbacks(new Callback[] { new ObjectProviderDispatcher(targetProvider), new EqualsHandler(),

-                new HashCodeHandler() });

-        @SuppressWarnings("unchecked") // type inference

-        final T result = (T) enhancer.create();

-        return result;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,

-            Class<?>... proxyClasses)

-    {

-        final Enhancer enhancer = new Enhancer();

-        enhancer.setClassLoader(classLoader);

-        enhancer.setInterfaces(toInterfaces(proxyClasses));

-        enhancer.setSuperclass(getSuperclass(proxyClasses));

-        enhancer.setCallbackFilter(CALLBACKFILTER);

-        enhancer.setCallbacks(new Callback[] { new InterceptorBridge(target, interceptor), new EqualsHandler(),

-                new HashCodeHandler() });

-        @SuppressWarnings("unchecked") // type inference

-        final T result = (T) enhancer.create();

-        return result;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses)

-    {

-        final Enhancer enhancer = new Enhancer();

-        enhancer.setClassLoader(classLoader);

-        enhancer.setInterfaces(toInterfaces(proxyClasses));

-        enhancer.setSuperclass(getSuperclass(proxyClasses));

-        enhancer.setCallbackFilter(CALLBACKFILTER);

-        enhancer.setCallbacks(

-                new Callback[] { new InvokerBridge(invoker), new EqualsHandler(), new HashCodeHandler() });

-        @SuppressWarnings("unchecked") // type inference

-        final T result = (T) enhancer.create();

-        return result;

-    }

-

-    //******************************************************************************************************************

-    // Inner Classes

-    //******************************************************************************************************************

-

-    private static class CglibProxyFactoryCallbackFilter implements CallbackFilter

-    {

-        @Override

-        public int accept(Method method)

-        {

-            if (ProxyUtils.isEqualsMethod(method))

-            {

-                return 1;

-            }

-            else if (ProxyUtils.isHashCode(method))

-            {

-                return 2;

-            }

-            else

-            {

-                return 0;

-            }

-        }

-    }

-

-    private static class EqualsHandler implements MethodInterceptor, Serializable

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        @Override

-        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable

-        {

-            return Boolean.valueOf(o == objects[0]);

-        }

-    }

-

-    private static class HashCodeHandler implements MethodInterceptor, Serializable

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        @Override

-        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable

-        {

-            return Integer.valueOf(System.identityHashCode(o));

-        }

-    }

-

-    private static class InterceptorBridge implements MethodInterceptor, Serializable

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        private final Object target;

-        private final Interceptor inner;

-

-        public InterceptorBridge(Object target, Interceptor inner)

-        {

-            this.inner = inner;

-            this.target = target;

-        }

-

-        @Override

-        public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable

-        {

-            return inner.intercept(new MethodProxyInvocation(object, target, method, args, methodProxy));

-        }

-    }

-

-    private static class InvokerBridge implements net.sf.cglib.proxy.InvocationHandler, Serializable

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        private final Invoker original;

-

-        public InvokerBridge(Invoker original)

-        {

-            this.original = original;

-        }

-

-        @Override

-        public Object invoke(Object object, Method method, Object[] objects) throws Throwable

-        {

-            return original.invoke(object, method, objects);

-        }

-    }

-

-    private static class MethodProxyInvocation implements Invocation

-    {

-        private final Object proxy;

-        private final Object target;

-        private final Method method;

-        private final Object[] args;

-        private final MethodProxy methodProxy;

-

-        public MethodProxyInvocation(Object proxy, Object target, Method method, Object[] args, MethodProxy methodProxy)

-        {

-            this.proxy = proxy;

-            this.target = target;

-            this.method = method;

-            this.methodProxy = methodProxy;

-            this.args = ObjectUtils.defaultIfNull(ArrayUtils.clone(args), ProxyUtils.EMPTY_ARGUMENTS);

-        }

-

-        @Override

-        public Method getMethod()

-        {

-            return method;

-        }

-

-        @Override

-        public Object[] getArguments()

-        {

-            return args;

-        }

-

-        @Override

-        public Object proceed() throws Throwable

-        {

-            return methodProxy.invoke(target, args);

-        }

-

-        @Override

-        public Object getProxy()

-        {

-            return proxy;

-        }

-    }

-

-    private static class ObjectProviderDispatcher implements Dispatcher, Serializable

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        private final ObjectProvider<?> delegateProvider;

-

-        public ObjectProviderDispatcher(ObjectProvider<?> delegateProvider)

-        {

-            this.delegateProvider = delegateProvider;

-        }

-

-        @Override

-        public Object loadObject()

-        {

-            return delegateProvider.getObject();

-        }

-    }

-}

+/*
+ * 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.proxy2.cglib;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Dispatcher;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.impl.AbstractSubclassingProxyFactory;
+
+/**
+ * Cglib-based {@link org.apache.commons.proxy2.ProxyFactory ProxyFactory} implementation.
+ */
+public class CglibProxyFactory extends AbstractSubclassingProxyFactory
+{
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private static final CallbackFilter CALLBACKFILTER = new CglibProxyFactoryCallbackFilter();
+
+    //******************************************************************************************************************
+    // ProxyFactory Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> targetProvider,
+            Class<?>... proxyClasses)
+    {
+        final Enhancer enhancer = new Enhancer();
+        enhancer.setClassLoader(classLoader);
+        enhancer.setInterfaces(toInterfaces(proxyClasses));
+        enhancer.setSuperclass(getSuperclass(proxyClasses));
+        enhancer.setCallbackFilter(CALLBACKFILTER);
+        enhancer.setCallbacks(new Callback[] { new ObjectProviderDispatcher(targetProvider), new EqualsHandler(),
+                new HashCodeHandler() });
+        @SuppressWarnings("unchecked") // type inference
+        final T result = (T) enhancer.create();
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
+            Class<?>... proxyClasses)
+    {
+        final Enhancer enhancer = new Enhancer();
+        enhancer.setClassLoader(classLoader);
+        enhancer.setInterfaces(toInterfaces(proxyClasses));
+        enhancer.setSuperclass(getSuperclass(proxyClasses));
+        enhancer.setCallbackFilter(CALLBACKFILTER);
+        enhancer.setCallbacks(new Callback[] { new InterceptorBridge(target, interceptor), new EqualsHandler(),
+                new HashCodeHandler() });
+        @SuppressWarnings("unchecked") // type inference
+        final T result = (T) enhancer.create();
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses)
+    {
+        final Enhancer enhancer = new Enhancer();
+        enhancer.setClassLoader(classLoader);
+        enhancer.setInterfaces(toInterfaces(proxyClasses));
+        enhancer.setSuperclass(getSuperclass(proxyClasses));
+        enhancer.setCallbackFilter(CALLBACKFILTER);
+        enhancer.setCallbacks(
+                new Callback[] { new InvokerBridge(invoker), new EqualsHandler(), new HashCodeHandler() });
+        @SuppressWarnings("unchecked") // type inference
+        final T result = (T) enhancer.create();
+        return result;
+    }
+
+    //******************************************************************************************************************
+    // Inner Classes
+    //******************************************************************************************************************
+
+    private static class CglibProxyFactoryCallbackFilter implements CallbackFilter
+    {
+        @Override
+        public int accept(Method method)
+        {
+            if (ProxyUtils.isEqualsMethod(method))
+            {
+                return 1;
+            }
+            else if (ProxyUtils.isHashCode(method))
+            {
+                return 2;
+            }
+            else
+            {
+                return 0;
+            }
+        }
+    }
+
+    private static class EqualsHandler implements MethodInterceptor, Serializable
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
+        {
+            return Boolean.valueOf(o == objects[0]);
+        }
+    }
+
+    private static class HashCodeHandler implements MethodInterceptor, Serializable
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
+        {
+            return Integer.valueOf(System.identityHashCode(o));
+        }
+    }
+
+    private static class InterceptorBridge implements MethodInterceptor, Serializable
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        private final Object target;
+        private final Interceptor inner;
+
+        public InterceptorBridge(Object target, Interceptor inner)
+        {
+            this.inner = inner;
+            this.target = target;
+        }
+
+        @Override
+        public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
+        {
+            return inner.intercept(new MethodProxyInvocation(object, target, method, args, methodProxy));
+        }
+    }
+
+    private static class InvokerBridge implements net.sf.cglib.proxy.InvocationHandler, Serializable
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        private final Invoker original;
+
+        public InvokerBridge(Invoker original)
+        {
+            this.original = original;
+        }
+
+        @Override
+        public Object invoke(Object object, Method method, Object[] objects) throws Throwable
+        {
+            return original.invoke(object, method, objects);
+        }
+    }
+
+    private static class MethodProxyInvocation implements Invocation
+    {
+        private final Object proxy;
+        private final Object target;
+        private final Method method;
+        private final Object[] args;
+        private final MethodProxy methodProxy;
+
+        public MethodProxyInvocation(Object proxy, Object target, Method method, Object[] args, MethodProxy methodProxy)
+        {
+            this.proxy = proxy;
+            this.target = target;
+            this.method = method;
+            this.methodProxy = methodProxy;
+            this.args = ObjectUtils.defaultIfNull(ArrayUtils.clone(args), ProxyUtils.EMPTY_ARGUMENTS);
+        }
+
+        @Override
+        public Method getMethod()
+        {
+            return method;
+        }
+
+        @Override
+        public Object[] getArguments()
+        {
+            return args;
+        }
+
+        @Override
+        public Object proceed() throws Throwable
+        {
+            return methodProxy.invoke(target, args);
+        }
+
+        @Override
+        public Object getProxy()
+        {
+            return proxy;
+        }
+    }
+
+    private static class ObjectProviderDispatcher implements Dispatcher, Serializable
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        private final ObjectProvider<?> delegateProvider;
+
+        public ObjectProviderDispatcher(ObjectProvider<?> delegateProvider)
+        {
+            this.delegateProvider = delegateProvider;
+        }
+
+        @Override
+        public Object loadObject()
+        {
+            return delegateProvider.getObject();
+        }
+    }
+}
diff --git a/cglib/src/test/java/org/apache/commons/proxy2/cglib/CglibProxyFactoryTest.java b/cglib/src/test/java/org/apache/commons/proxy2/cglib/CglibProxyFactoryTest.java
index 29713c7..b16dbe4 100644
--- a/cglib/src/test/java/org/apache/commons/proxy2/cglib/CglibProxyFactoryTest.java
+++ b/cglib/src/test/java/org/apache/commons/proxy2/cglib/CglibProxyFactoryTest.java
@@ -1,31 +1,31 @@
-/*

- * 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.proxy2.cglib;

-

-import org.apache.commons.proxy2.AbstractSubclassingProxyFactoryTestCase;

-

-public class CglibProxyFactoryTest extends AbstractSubclassingProxyFactoryTestCase

-{

-    //**********************************************************************************************************************

-    // Constructors

-    //**********************************************************************************************************************

-

-    public CglibProxyFactoryTest()

-    {

-    }

-}

+/*
+ * 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.proxy2.cglib;
+
+import org.apache.commons.proxy2.AbstractSubclassingProxyFactoryTestCase;
+
+public class CglibProxyFactoryTest extends AbstractSubclassingProxyFactoryTestCase
+{
+    //**********************************************************************************************************************
+    // Constructors
+    //**********************************************************************************************************************
+
+    public CglibProxyFactoryTest()
+    {
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/Invocation.java b/core/src/main/java/org/apache/commons/proxy2/Invocation.java
index 80629d8..1c85f63 100644
--- a/core/src/main/java/org/apache/commons/proxy2/Invocation.java
+++ b/core/src/main/java/org/apache/commons/proxy2/Invocation.java
@@ -1,63 +1,63 @@
-/*

- * 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.proxy2;

-

-import java.lang.reflect.Method;

-

-/**

- * Method invocation for use by an {@link Interceptor}.

- * 

- * @since 1.0

- */

-public interface Invocation

-{

-    //******************************************************************************************************************

-    // Other Methods

-    //******************************************************************************************************************

-

-    /**

-     * Returns the arguments being passed to this method invocation. Changes in the elements of this array will be

-     * propagated to the recipient of this invocation.

-     * 

-     * @return the arguments being passed to this method invocation

-     */

-    Object[] getArguments();

-

-    /**

-     * Returns the method being called.

-     * 

-     * @return the method being called

-     */

-    Method getMethod();

-

-    /**

-     * Returns the proxy object on which this invocation was invoked.

-     * 

-     * @return the proxy object on which this invocation was invoked

-     */

-    Object getProxy();

-

-    /**

-     * Called in order to let the invocation proceed.

-     * 

-     * @return the return value of the invocation

-     * @throws Throwable

-     *             any exception or error that was thrown as a result of this invocation

-     */

-    Object proceed() throws Throwable;

-}

+/*
+ * 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.proxy2;
+
+import java.lang.reflect.Method;
+
+/**
+ * Method invocation for use by an {@link Interceptor}.
+ * 
+ * @since 1.0
+ */
+public interface Invocation
+{
+    //******************************************************************************************************************
+    // Other Methods
+    //******************************************************************************************************************
+
+    /**
+     * Returns the arguments being passed to this method invocation. Changes in the elements of this array will be
+     * propagated to the recipient of this invocation.
+     * 
+     * @return the arguments being passed to this method invocation
+     */
+    Object[] getArguments();
+
+    /**
+     * Returns the method being called.
+     * 
+     * @return the method being called
+     */
+    Method getMethod();
+
+    /**
+     * Returns the proxy object on which this invocation was invoked.
+     * 
+     * @return the proxy object on which this invocation was invoked
+     */
+    Object getProxy();
+
+    /**
+     * Called in order to let the invocation proceed.
+     * 
+     * @return the return value of the invocation
+     * @throws Throwable
+     *             any exception or error that was thrown as a result of this invocation
+     */
+    Object proceed() throws Throwable;
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/Invoker.java b/core/src/main/java/org/apache/commons/proxy2/Invoker.java
index 699c031..acc91b0 100644
--- a/core/src/main/java/org/apache/commons/proxy2/Invoker.java
+++ b/core/src/main/java/org/apache/commons/proxy2/Invoker.java
@@ -1,49 +1,49 @@
-/*

- * 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.proxy2;

-

-import java.io.Serializable;

-import java.lang.reflect.Method;

-

-/**

- * An invoker is responsible for handling a method invocation.

- * 

- * @since 1.0

- */

-public interface Invoker extends Serializable

-{

-    //******************************************************************************************************************

-    // Other Methods

-    //******************************************************************************************************************

-

-    /**

-     * "Invokes" the method. Implementation should throw a {@link org.apache.commons.proxy2.exception.InvokerException}

-     * if problems arise while trying to invoke the method.

-     * 

-     * @param proxy

-     *            the proxy2 object

-     * @param method

-     *            the method being invoked

-     * @param arguments

-     *            the arguments

-     * @return the return value

-     * @throws Throwable

-     *             thrown by the implementation

-     */

-    Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable;

-}

+/*
+ * 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.proxy2;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+/**
+ * An invoker is responsible for handling a method invocation.
+ * 
+ * @since 1.0
+ */
+public interface Invoker extends Serializable
+{
+    //******************************************************************************************************************
+    // Other Methods
+    //******************************************************************************************************************
+
+    /**
+     * "Invokes" the method. Implementation should throw a {@link org.apache.commons.proxy2.exception.InvokerException}
+     * if problems arise while trying to invoke the method.
+     * 
+     * @param proxy
+     *            the proxy2 object
+     * @param method
+     *            the method being invoked
+     * @param arguments
+     *            the arguments
+     * @return the return value
+     * @throws Throwable
+     *             thrown by the implementation
+     */
+    Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable;
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/ObjectProvider.java b/core/src/main/java/org/apache/commons/proxy2/ObjectProvider.java
index 86b1a04..5f2d7d8 100644
--- a/core/src/main/java/org/apache/commons/proxy2/ObjectProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/ObjectProvider.java
@@ -1,41 +1,41 @@
-/*

- * 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.proxy2;

-

-import java.io.Serializable;

-

-/**

- * Provides an object to a delegating proxy.

- * 

- * @since 1.0

- */

-public interface ObjectProvider<T> extends Serializable

-{

-    //******************************************************************************************************************

-    // Other Methods

-    //******************************************************************************************************************

-

-    /**

-     * Returns an object. Implementing classes should throw a

-     * {@link org.apache.commons.proxy2.exception.ObjectProviderException} if any problems arise while

-     * constructing/finding the object.

-     * 

-     * @return the object on which the method should be called

-     */

-    T getObject();

-}

+/*
+ * 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.proxy2;
+
+import java.io.Serializable;
+
+/**
+ * Provides an object to a delegating proxy.
+ * 
+ * @since 1.0
+ */
+public interface ObjectProvider<T> extends Serializable
+{
+    //******************************************************************************************************************
+    // Other Methods
+    //******************************************************************************************************************
+
+    /**
+     * Returns an object. Implementing classes should throw a
+     * {@link org.apache.commons.proxy2.exception.ObjectProviderException} if any problems arise while
+     * constructing/finding the object.
+     * 
+     * @return the object on which the method should be called
+     */
+    T getObject();
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/ProxyFactory.java b/core/src/main/java/org/apache/commons/proxy2/ProxyFactory.java
index 257f499..82bd20a 100644
--- a/core/src/main/java/org/apache/commons/proxy2/ProxyFactory.java
+++ b/core/src/main/java/org/apache/commons/proxy2/ProxyFactory.java
@@ -1,122 +1,122 @@
-/*

- * 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.proxy2;

-

-/**

- * ProxyFactory interface.

- * 

- * @since 2.0

- */

-public interface ProxyFactory

-{

-    //******************************************************************************************************************

-    // Other Methods

-    //******************************************************************************************************************

-

-    /**

-     * Learn whether this {@link ProxyFactory} is capable of creating a proxy for the specified set of classes.

-     * 

-     * @param proxyClasses

-     *            the proxy2 classes

-     * @return boolean

-     */

-    boolean canProxy(Class<?>... proxyClasses);

-

-    /**

-     * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>. The proxy will be

-     * generated using the current thread's "context class loader."

-     * 

-     * @param delegateProvider

-     *            the delegate provider

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement

-     * @return a proxy which delegates to the object provided by the target object provider

-     */

-    <T> T createDelegatorProxy(ObjectProvider<?> delegateProvider, Class<?>... proxyClasses);

-

-    /**

-     * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>.

-     * 

-     * @param classLoader

-     *            the class loader to use when generating the proxy

-     * @param delegateProvider

-     *            the delegate provider

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement

-     * @return a proxy which delegates to the object provided by the target <code>delegateProvider>

-     */

-    <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> delegateProvider, Class<?>... proxyClasses);

-

-    /**

-     * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the

-     * <code>target</code> object. The proxy will be generated using the current thread's "context class loader."

-     * 

-     * @param target

-     *            the target object

-     * @param interceptor

-     *            the method interceptor

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement

-     * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the

-     *         <code>target</code> object.

-     */

-    <T> T createInterceptorProxy(Object target, Interceptor interceptor, Class<?>... proxyClasses);

-

-    /**

-     * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the

-     * <code>target</code> object.

-     * 

-     * @param classLoader

-     *            the class loader to use when generating the proxy

-     * @param target

-     *            the target object

-     * @param interceptor

-     *            the method interceptor

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement.

-     * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the

-     *         <code>target</code> object.

-     */

-    <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,

-            Class<?>... proxyClasses);

-

-    /**

-     * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations. The proxy will be

-     * generated using the current thread's "context class loader."

-     * 

-     * @param invoker

-     *            the invoker

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement

-     * @return a proxy which uses the provided {@link Invoker} to handle all method invocations

-     */

-    <T> T createInvokerProxy(Invoker invoker, Class<?>... proxyClasses);

-

-    /**

-     * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations.

-     * 

-     * @param classLoader

-     *            the class loader to use when generating the proxy

-     * @param invoker

-     *            the invoker

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement

-     * @return a proxy which uses the provided {@link Invoker} to handle all method invocations

-     */

-    <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses);

-}

+/*
+ * 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.proxy2;
+
+/**
+ * ProxyFactory interface.
+ * 
+ * @since 2.0
+ */
+public interface ProxyFactory
+{
+    //******************************************************************************************************************
+    // Other Methods
+    //******************************************************************************************************************
+
+    /**
+     * Learn whether this {@link ProxyFactory} is capable of creating a proxy for the specified set of classes.
+     * 
+     * @param proxyClasses
+     *            the proxy2 classes
+     * @return boolean
+     */
+    boolean canProxy(Class<?>... proxyClasses);
+
+    /**
+     * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>. The proxy will be
+     * generated using the current thread's "context class loader."
+     * 
+     * @param delegateProvider
+     *            the delegate provider
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement
+     * @return a proxy which delegates to the object provided by the target object provider
+     */
+    <T> T createDelegatorProxy(ObjectProvider<?> delegateProvider, Class<?>... proxyClasses);
+
+    /**
+     * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>.
+     * 
+     * @param classLoader
+     *            the class loader to use when generating the proxy
+     * @param delegateProvider
+     *            the delegate provider
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement
+     * @return a proxy which delegates to the object provided by the target <code>delegateProvider>
+     */
+    <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> delegateProvider, Class<?>... proxyClasses);
+
+    /**
+     * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+     * <code>target</code> object. The proxy will be generated using the current thread's "context class loader."
+     * 
+     * @param target
+     *            the target object
+     * @param interceptor
+     *            the method interceptor
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement
+     * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+     *         <code>target</code> object.
+     */
+    <T> T createInterceptorProxy(Object target, Interceptor interceptor, Class<?>... proxyClasses);
+
+    /**
+     * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+     * <code>target</code> object.
+     * 
+     * @param classLoader
+     *            the class loader to use when generating the proxy
+     * @param target
+     *            the target object
+     * @param interceptor
+     *            the method interceptor
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement.
+     * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+     *         <code>target</code> object.
+     */
+    <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
+            Class<?>... proxyClasses);
+
+    /**
+     * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations. The proxy will be
+     * generated using the current thread's "context class loader."
+     * 
+     * @param invoker
+     *            the invoker
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement
+     * @return a proxy which uses the provided {@link Invoker} to handle all method invocations
+     */
+    <T> T createInvokerProxy(Invoker invoker, Class<?>... proxyClasses);
+
+    /**
+     * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations.
+     * 
+     * @param classLoader
+     *            the class loader to use when generating the proxy
+     * @param invoker
+     *            the invoker
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement
+     * @return a proxy which uses the provided {@link Invoker} to handle all method invocations
+     */
+    <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses);
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/ProxyUtils.java b/core/src/main/java/org/apache/commons/proxy2/ProxyUtils.java
index 7fd0ab5..24b517c 100644
--- a/core/src/main/java/org/apache/commons/proxy2/ProxyUtils.java
+++ b/core/src/main/java/org/apache/commons/proxy2/ProxyUtils.java
@@ -1,191 +1,191 @@
-/*

- * 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.proxy2;

-

-import java.lang.reflect.Method;

-import java.util.Collections;

-import java.util.HashMap;

-import java.util.Map;

-

-import org.apache.commons.lang3.ArrayUtils;

-import org.apache.commons.lang3.ClassUtils;

-

-/**

- * Provides some helpful proxy utility methods.

- * 

- * @since 1.0

- */

-public final class ProxyUtils

-{

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    public static final Object[] EMPTY_ARGUMENTS = ArrayUtils.EMPTY_OBJECT_ARRAY;

-    public static final Class<?>[] EMPTY_ARGUMENT_TYPES = ArrayUtils.EMPTY_CLASS_ARRAY;

-    private static final Map<Class<?>, Class<?>> WRAPPER_CLASS_MAP;

-    private static final Map<Class<?>, Object> NULL_VALUE_MAP;

-

-    //******************************************************************************************************************

-    // Static Methods

-    //******************************************************************************************************************

-

-    static

-    {

-        final Map<Class<?>, Class<?>> wrappers = new HashMap<Class<?>, Class<?>>();

-        wrappers.put(Integer.TYPE, Integer.class);

-        wrappers.put(Character.TYPE, Character.class);

-        wrappers.put(Boolean.TYPE, Boolean.class);

-        wrappers.put(Short.TYPE, Short.class);

-        wrappers.put(Long.TYPE, Long.class);

-        wrappers.put(Float.TYPE, Float.class);

-        wrappers.put(Double.TYPE, Double.class);

-        wrappers.put(Byte.TYPE, Byte.class);

-        WRAPPER_CLASS_MAP = Collections.unmodifiableMap(wrappers);

-    }

-

-    static

-    {

-        final Map<Class<?>, Object> nullValues = new HashMap<Class<?>, Object>();

-        nullValues.put(Integer.TYPE, Integer.valueOf(0));

-        nullValues.put(Long.TYPE, Long.valueOf(0));

-        nullValues.put(Short.TYPE, Short.valueOf((short) 0));

-        nullValues.put(Byte.TYPE, Byte.valueOf((byte) 0));

-        nullValues.put(Float.TYPE, Float.valueOf(0.0f));

-        nullValues.put(Double.TYPE, Double.valueOf(0.0));

-        nullValues.put(Character.TYPE, Character.valueOf((char) 0));

-        nullValues.put(Boolean.TYPE, Boolean.FALSE);

-        NULL_VALUE_MAP = Collections.unmodifiableMap(nullValues);

-    }

-

-    /**

-     * <p>

-     * Gets an array of {@link Class} objects representing all interfaces implemented by the given class and its

-     * superclasses.

-     * </p>

-     * <p/>

-     * <p>

-     * The order is determined by looking through each interface in turn as declared in the source file and following

-     * its hierarchy up. Then each superclass is considered in the same way. Later duplicates are ignored, so the order

-     * is maintained.

-     * </p>

-     * <p/>

-     * <b>Note</b>: Implementation of this method was "borrowed" from <a href="http://commons.apache.org/lang/">Apache

-     * Commons Lang</a> to avoid a dependency.

-     * </p>

-     * 

-     * @param cls

-     *            the class to look up, may be <code>null</code>

-     * @return an array of {@link Class} objects representing all interfaces implemented by the given class and its

-     *         superclasses or <code>null</code> if input class is null.

-     */

-    public static Class<?>[] getAllInterfaces(Class<?> cls)

-    {

-        return cls == null ? null : ClassUtils.getAllInterfaces(cls).toArray(ArrayUtils.EMPTY_CLASS_ARRAY);

-    }

-

-    /**

-     * Returns the class name as you would expect to see it in Java code.

-     * <p/>

-     * <b>Examples:</b>

-     * <ul>

-     * <li>getJavaClassName( Object[].class ) == "Object[]"</li>

-     * <li>getJavaClassName( Object[][].class ) == "Object[][]"</li>

-     * <li>getJavaClassName( Integer.TYPE ) == "int"</li>

-     * </p>

-     * 

-     * @param clazz

-     *            the class

-     * @return the class' name as you would expect to see it in Java code

-     */

-    public static String getJavaClassName(Class<?> clazz)

-    {

-        if (clazz.isArray())

-        {

-            return getJavaClassName(clazz.getComponentType()) + "[]";

-        }

-        return clazz.getName();

-    }

-

-    /**

-     * Returns the wrapper class for the given primitive type.

-     * 

-     * @param primitiveType

-     *            the primitive type

-     * @return the wrapper class

-     */

-    public static Class<?> getWrapperClass(Class<?> primitiveType)

-    {

-        return WRAPPER_CLASS_MAP.get(primitiveType);

-    }

-

-    /**

-     * Returns the proper "null value" as specified by the Java language.

-     * 

-     * @param type

-     *            the type

-     * @return the null value

-     */

-    public static <T> T nullValue(Class<T> type)

-    {

-        @SuppressWarnings("unchecked") // map only contains matching type/value entries

-        final T result = (T) NULL_VALUE_MAP.get(type);

-        return result;

-    }

-

-    /**

-     * Learn whether the specified method is/overrides {@link Object#equals(Object)}.

-     * 

-     * @param method

-     *            to compare

-     * @return <code>true</code> for a method with signature <code>boolean equals(Object)</code>

-     */

-    public static boolean isEqualsMethod(Method method)

-    {

-        return "equals".equals(method.getName()) && Boolean.TYPE.equals(method.getReturnType())

-                && method.getParameterTypes().length == 1 && Object.class.equals(method.getParameterTypes()[0]);

-    }

-

-    /**

-     * Learn whether the specified method is/overrides {@link Object#hashCode()}.

-     * 

-     * @param method

-     *            to compare

-     * @return true for a method with signature <code>int hashCode()</code>

-     */

-    public static boolean isHashCode(Method method)

-    {

-        return "hashCode".equals(method.getName()) && Integer.TYPE.equals(method.getReturnType())

-                && method.getParameterTypes().length == 0;

-    }

-

-    /**

-     * Get a {@link ProxyFactory} that delegates to discoverable {@link ProxyFactory} service providers.

-     * 

-     * @return {@link ProxyFactory}

-     */

-    public static ProxyFactory proxyFactory()

-    {

-        return DefaultProxyFactory.INSTANCE;

-    }

-

-    private ProxyUtils()

-    {

-        // Hiding constructor in utility class!

-    }

-}

+/*
+ * 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.proxy2;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.ClassUtils;
+
+/**
+ * Provides some helpful proxy utility methods.
+ * 
+ * @since 1.0
+ */
+public final class ProxyUtils
+{
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    public static final Object[] EMPTY_ARGUMENTS = ArrayUtils.EMPTY_OBJECT_ARRAY;
+    public static final Class<?>[] EMPTY_ARGUMENT_TYPES = ArrayUtils.EMPTY_CLASS_ARRAY;
+    private static final Map<Class<?>, Class<?>> WRAPPER_CLASS_MAP;
+    private static final Map<Class<?>, Object> NULL_VALUE_MAP;
+
+    //******************************************************************************************************************
+    // Static Methods
+    //******************************************************************************************************************
+
+    static
+    {
+        final Map<Class<?>, Class<?>> wrappers = new HashMap<Class<?>, Class<?>>();
+        wrappers.put(Integer.TYPE, Integer.class);
+        wrappers.put(Character.TYPE, Character.class);
+        wrappers.put(Boolean.TYPE, Boolean.class);
+        wrappers.put(Short.TYPE, Short.class);
+        wrappers.put(Long.TYPE, Long.class);
+        wrappers.put(Float.TYPE, Float.class);
+        wrappers.put(Double.TYPE, Double.class);
+        wrappers.put(Byte.TYPE, Byte.class);
+        WRAPPER_CLASS_MAP = Collections.unmodifiableMap(wrappers);
+    }
+
+    static
+    {
+        final Map<Class<?>, Object> nullValues = new HashMap<Class<?>, Object>();
+        nullValues.put(Integer.TYPE, Integer.valueOf(0));
+        nullValues.put(Long.TYPE, Long.valueOf(0));
+        nullValues.put(Short.TYPE, Short.valueOf((short) 0));
+        nullValues.put(Byte.TYPE, Byte.valueOf((byte) 0));
+        nullValues.put(Float.TYPE, Float.valueOf(0.0f));
+        nullValues.put(Double.TYPE, Double.valueOf(0.0));
+        nullValues.put(Character.TYPE, Character.valueOf((char) 0));
+        nullValues.put(Boolean.TYPE, Boolean.FALSE);
+        NULL_VALUE_MAP = Collections.unmodifiableMap(nullValues);
+    }
+
+    /**
+     * <p>
+     * Gets an array of {@link Class} objects representing all interfaces implemented by the given class and its
+     * superclasses.
+     * </p>
+     * <p/>
+     * <p>
+     * The order is determined by looking through each interface in turn as declared in the source file and following
+     * its hierarchy up. Then each superclass is considered in the same way. Later duplicates are ignored, so the order
+     * is maintained.
+     * </p>
+     * <p/>
+     * <b>Note</b>: Implementation of this method was "borrowed" from <a href="http://commons.apache.org/lang/">Apache
+     * Commons Lang</a> to avoid a dependency.
+     * </p>
+     * 
+     * @param cls
+     *            the class to look up, may be <code>null</code>
+     * @return an array of {@link Class} objects representing all interfaces implemented by the given class and its
+     *         superclasses or <code>null</code> if input class is null.
+     */
+    public static Class<?>[] getAllInterfaces(Class<?> cls)
+    {
+        return cls == null ? null : ClassUtils.getAllInterfaces(cls).toArray(ArrayUtils.EMPTY_CLASS_ARRAY);
+    }
+
+    /**
+     * Returns the class name as you would expect to see it in Java code.
+     * <p/>
+     * <b>Examples:</b>
+     * <ul>
+     * <li>getJavaClassName( Object[].class ) == "Object[]"</li>
+     * <li>getJavaClassName( Object[][].class ) == "Object[][]"</li>
+     * <li>getJavaClassName( Integer.TYPE ) == "int"</li>
+     * </p>
+     * 
+     * @param clazz
+     *            the class
+     * @return the class' name as you would expect to see it in Java code
+     */
+    public static String getJavaClassName(Class<?> clazz)
+    {
+        if (clazz.isArray())
+        {
+            return getJavaClassName(clazz.getComponentType()) + "[]";
+        }
+        return clazz.getName();
+    }
+
+    /**
+     * Returns the wrapper class for the given primitive type.
+     * 
+     * @param primitiveType
+     *            the primitive type
+     * @return the wrapper class
+     */
+    public static Class<?> getWrapperClass(Class<?> primitiveType)
+    {
+        return WRAPPER_CLASS_MAP.get(primitiveType);
+    }
+
+    /**
+     * Returns the proper "null value" as specified by the Java language.
+     * 
+     * @param type
+     *            the type
+     * @return the null value
+     */
+    public static <T> T nullValue(Class<T> type)
+    {
+        @SuppressWarnings("unchecked") // map only contains matching type/value entries
+        final T result = (T) NULL_VALUE_MAP.get(type);
+        return result;
+    }
+
+    /**
+     * Learn whether the specified method is/overrides {@link Object#equals(Object)}.
+     * 
+     * @param method
+     *            to compare
+     * @return <code>true</code> for a method with signature <code>boolean equals(Object)</code>
+     */
+    public static boolean isEqualsMethod(Method method)
+    {
+        return "equals".equals(method.getName()) && Boolean.TYPE.equals(method.getReturnType())
+                && method.getParameterTypes().length == 1 && Object.class.equals(method.getParameterTypes()[0]);
+    }
+
+    /**
+     * Learn whether the specified method is/overrides {@link Object#hashCode()}.
+     * 
+     * @param method
+     *            to compare
+     * @return true for a method with signature <code>int hashCode()</code>
+     */
+    public static boolean isHashCode(Method method)
+    {
+        return "hashCode".equals(method.getName()) && Integer.TYPE.equals(method.getReturnType())
+                && method.getParameterTypes().length == 0;
+    }
+
+    /**
+     * Get a {@link ProxyFactory} that delegates to discoverable {@link ProxyFactory} service providers.
+     * 
+     * @return {@link ProxyFactory}
+     */
+    public static ProxyFactory proxyFactory()
+    {
+        return DefaultProxyFactory.INSTANCE;
+    }
+
+    private ProxyUtils()
+    {
+        // Hiding constructor in utility class!
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/exception/InvokerException.java b/core/src/main/java/org/apache/commons/proxy2/exception/InvokerException.java
index f3417d8..3754ead 100644
--- a/core/src/main/java/org/apache/commons/proxy2/exception/InvokerException.java
+++ b/core/src/main/java/org/apache/commons/proxy2/exception/InvokerException.java
@@ -1,71 +1,71 @@
-/*

- * 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.proxy2.exception;

-

-/**

- * To be used by an {@link org.apache.commons.proxy2.Invoker} when they encounter an error.

- * 

- * @since 1.0

- */

-public class InvokerException extends RuntimeException

-{

-    /** Serialization version */

-    private static final long serialVersionUID = -1L;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new InvokerException instance.

-     */

-    public InvokerException()

-    {

-    }

-

-    /**

-     * Create a new InvokerException instance.

-     * 

-     * @param message

-     */

-    public InvokerException(String message)

-    {

-        super(message);

-    }

-

-    /**

-     * Create a new InvokerException instance.

-     * 

-     * @param cause

-     */

-    public InvokerException(Throwable cause)

-    {

-        super(cause);

-    }

-

-    /**

-     * Create a new InvokerException instance.

-     * 

-     * @param message

-     * @param cause

-     */

-    public InvokerException(String message, Throwable cause)

-    {

-        super(message, cause);

-    }

-}

+/*
+ * 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.proxy2.exception;
+
+/**
+ * To be used by an {@link org.apache.commons.proxy2.Invoker} when they encounter an error.
+ * 
+ * @since 1.0
+ */
+public class InvokerException extends RuntimeException
+{
+    /** Serialization version */
+    private static final long serialVersionUID = -1L;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new InvokerException instance.
+     */
+    public InvokerException()
+    {
+    }
+
+    /**
+     * Create a new InvokerException instance.
+     * 
+     * @param message
+     */
+    public InvokerException(String message)
+    {
+        super(message);
+    }
+
+    /**
+     * Create a new InvokerException instance.
+     * 
+     * @param cause
+     */
+    public InvokerException(Throwable cause)
+    {
+        super(cause);
+    }
+
+    /**
+     * Create a new InvokerException instance.
+     * 
+     * @param message
+     * @param cause
+     */
+    public InvokerException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/exception/ObjectProviderException.java b/core/src/main/java/org/apache/commons/proxy2/exception/ObjectProviderException.java
index ebadda0..014a8b4 100644
--- a/core/src/main/java/org/apache/commons/proxy2/exception/ObjectProviderException.java
+++ b/core/src/main/java/org/apache/commons/proxy2/exception/ObjectProviderException.java
@@ -1,95 +1,95 @@
-/*

- * 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.proxy2.exception;

-

-/**

- * {@link org.apache.commons.proxy2.ObjectProvider} implementations should throw this exception type to indicate that

- * there was a problem creating/finding the object.

- * 

- * @since 1.0

- */

-public class ObjectProviderException extends RuntimeException

-{

-    /** Serialization version */

-    private static final long serialVersionUID = -1L;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new ObjectProviderException instance.

-     */

-    public ObjectProviderException()

-    {

-    }

-

-    /**

-     * Create a new ObjectProviderException instance.

-     * 

-     * @param message

-     */

-    public ObjectProviderException(String message)

-    {

-        super(message);

-    }

-

-    /**

-     * Create a new ObjectProviderException instance using {@link String#format(String, Object...)} for the message.

-     * 

-     * @param message

-     * @param arguments

-     */

-    public ObjectProviderException(String message, Object... arguments)

-    {

-        super(String.format(message, arguments));

-    }

-

-    /**

-     * Create a new ObjectProviderException instance.

-     * 

-     * @param cause

-     */

-    public ObjectProviderException(Throwable cause)

-    {

-        super(cause);

-    }

-

-    /**

-     * Create a new ObjectProviderException instance.

-     * 

-     * @param message

-     * @param cause

-     */

-    public ObjectProviderException(String message, Throwable cause)

-    {

-        super(message, cause);

-    }

-

-    /**

-     * Create a new ObjectProviderException instance using {@link String#format(String, Object...)} for the message.

-     * 

-     * @param cause

-     * @param message

-     * @param arguments

-     */

-    public ObjectProviderException(Throwable cause, String message, Object... arguments)

-    {

-        super(String.format(message, arguments), cause);

-    }

-}

+/*
+ * 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.proxy2.exception;
+
+/**
+ * {@link org.apache.commons.proxy2.ObjectProvider} implementations should throw this exception type to indicate that
+ * there was a problem creating/finding the object.
+ * 
+ * @since 1.0
+ */
+public class ObjectProviderException extends RuntimeException
+{
+    /** Serialization version */
+    private static final long serialVersionUID = -1L;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new ObjectProviderException instance.
+     */
+    public ObjectProviderException()
+    {
+    }
+
+    /**
+     * Create a new ObjectProviderException instance.
+     * 
+     * @param message
+     */
+    public ObjectProviderException(String message)
+    {
+        super(message);
+    }
+
+    /**
+     * Create a new ObjectProviderException instance using {@link String#format(String, Object...)} for the message.
+     * 
+     * @param message
+     * @param arguments
+     */
+    public ObjectProviderException(String message, Object... arguments)
+    {
+        super(String.format(message, arguments));
+    }
+
+    /**
+     * Create a new ObjectProviderException instance.
+     * 
+     * @param cause
+     */
+    public ObjectProviderException(Throwable cause)
+    {
+        super(cause);
+    }
+
+    /**
+     * Create a new ObjectProviderException instance.
+     * 
+     * @param message
+     * @param cause
+     */
+    public ObjectProviderException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+
+    /**
+     * Create a new ObjectProviderException instance using {@link String#format(String, Object...)} for the message.
+     * 
+     * @param cause
+     * @param message
+     * @param arguments
+     */
+    public ObjectProviderException(Throwable cause, String message, Object... arguments)
+    {
+        super(String.format(message, arguments), cause);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/exception/ProxyFactoryException.java b/core/src/main/java/org/apache/commons/proxy2/exception/ProxyFactoryException.java
index ed0883d..99b967d 100644
--- a/core/src/main/java/org/apache/commons/proxy2/exception/ProxyFactoryException.java
+++ b/core/src/main/java/org/apache/commons/proxy2/exception/ProxyFactoryException.java
@@ -1,72 +1,72 @@
-/*

- * 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.proxy2.exception;

-

-/**

- * A runtime exception type to be used by {@link org.apache.commons.proxy2.ProxyFactory proxy factories} when a problem

- * occurs.

- * 

- * @since 1.0

- */

-public class ProxyFactoryException extends RuntimeException

-{

-    /** Serialization version */

-    private static final long serialVersionUID = -1L;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new ProxyFactoryException instance.

-     */

-    public ProxyFactoryException()

-    {

-    }

-

-    /**

-     * Create a new ProxyFactoryException instance.

-     * 

-     * @param message

-     */

-    public ProxyFactoryException(String message)

-    {

-        super(message);

-    }

-

-    /**

-     * Create a new ProxyFactoryException instance.

-     * 

-     * @param cause

-     */

-    public ProxyFactoryException(Throwable cause)

-    {

-        super(cause);

-    }

-

-    /**

-     * Create a new ProxyFactoryException instance.

-     * 

-     * @param message

-     * @param cause

-     */

-    public ProxyFactoryException(String message, Throwable cause)

-    {

-        super(message, cause);

-    }

-}

+/*
+ * 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.proxy2.exception;
+
+/**
+ * A runtime exception type to be used by {@link org.apache.commons.proxy2.ProxyFactory proxy factories} when a problem
+ * occurs.
+ * 
+ * @since 1.0
+ */
+public class ProxyFactoryException extends RuntimeException
+{
+    /** Serialization version */
+    private static final long serialVersionUID = -1L;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new ProxyFactoryException instance.
+     */
+    public ProxyFactoryException()
+    {
+    }
+
+    /**
+     * Create a new ProxyFactoryException instance.
+     * 
+     * @param message
+     */
+    public ProxyFactoryException(String message)
+    {
+        super(message);
+    }
+
+    /**
+     * Create a new ProxyFactoryException instance.
+     * 
+     * @param cause
+     */
+    public ProxyFactoryException(Throwable cause)
+    {
+        super(cause);
+    }
+
+    /**
+     * Create a new ProxyFactoryException instance.
+     * 
+     * @param message
+     * @param cause
+     */
+    public ProxyFactoryException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyClassGenerator.java b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyClassGenerator.java
index cc8cab4..abac5c8 100644
--- a/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyClassGenerator.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyClassGenerator.java
@@ -1,76 +1,76 @@
-/*

- * 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.proxy2.impl;

-

-import java.lang.reflect.Method;

-import java.lang.reflect.Modifier;

-import java.util.Collection;

-import java.util.HashMap;

-import java.util.HashSet;

-import java.util.Map;

-import java.util.Set;

-

-/**

- * A useful superclass for {@link ProxyClassGenerator} implementations.

- * 

- * @since 1.0

- */

-public abstract class AbstractProxyClassGenerator implements ProxyClassGenerator

-{

-    //******************************************************************************************************************

-    // Static Methods

-    //******************************************************************************************************************

-

-    /**

-     * Returns all methods that a proxy class must implement from the proxy interfaces. This method makes sure there are

-     * no method signature clashes. For methods with the same signature (name and parameter types), the one encountered

-     * first will be returned in the result. Final methods are also excluded from the result.

-     * 

-     * @param proxyClasses

-     *            the interfaces the proxy class must implement

-     * @return all methods that the proxy class must implement

-     */

-    public static Method[] getImplementationMethods(Class<?>[] proxyClasses)

-    {

-        final Map<MethodSignature, Method> signatureMethodMap = new HashMap<MethodSignature, Method>();

-        final Set<MethodSignature> finalizedSignatures = new HashSet<MethodSignature>();

-        for (int i = 0; i < proxyClasses.length; i++)

-        {

-            Class<?> proxyInterface = proxyClasses[i];

-            final Method[] methods = proxyInterface.getMethods();

-            for (int j = 0; j < methods.length; j++)

-            {

-                final MethodSignature signature = new MethodSignature(methods[j]);

-                if (Modifier.isFinal(methods[j].getModifiers()))

-                {

-                    finalizedSignatures.add(signature);

-                }

-                else if (!signatureMethodMap.containsKey(signature))

-                {

-                    signatureMethodMap.put(signature, methods[j]);

-                }

-            }

-        }

-        final Collection<Method> resultingMethods = signatureMethodMap.values();

-        for (MethodSignature signature : finalizedSignatures)

-        {

-            resultingMethods.remove(signatureMethodMap.get(signature));

-        }

-        return resultingMethods.toArray(new Method[resultingMethods.size()]);

-    }

-}

+/*
+ * 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.proxy2.impl;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A useful superclass for {@link ProxyClassGenerator} implementations.
+ * 
+ * @since 1.0
+ */
+public abstract class AbstractProxyClassGenerator implements ProxyClassGenerator
+{
+    //******************************************************************************************************************
+    // Static Methods
+    //******************************************************************************************************************
+
+    /**
+     * Returns all methods that a proxy class must implement from the proxy interfaces. This method makes sure there are
+     * no method signature clashes. For methods with the same signature (name and parameter types), the one encountered
+     * first will be returned in the result. Final methods are also excluded from the result.
+     * 
+     * @param proxyClasses
+     *            the interfaces the proxy class must implement
+     * @return all methods that the proxy class must implement
+     */
+    public static Method[] getImplementationMethods(Class<?>[] proxyClasses)
+    {
+        final Map<MethodSignature, Method> signatureMethodMap = new HashMap<MethodSignature, Method>();
+        final Set<MethodSignature> finalizedSignatures = new HashSet<MethodSignature>();
+        for (int i = 0; i < proxyClasses.length; i++)
+        {
+            Class<?> proxyInterface = proxyClasses[i];
+            final Method[] methods = proxyInterface.getMethods();
+            for (int j = 0; j < methods.length; j++)
+            {
+                final MethodSignature signature = new MethodSignature(methods[j]);
+                if (Modifier.isFinal(methods[j].getModifiers()))
+                {
+                    finalizedSignatures.add(signature);
+                }
+                else if (!signatureMethodMap.containsKey(signature))
+                {
+                    signatureMethodMap.put(signature, methods[j]);
+                }
+            }
+        }
+        final Collection<Method> resultingMethods = signatureMethodMap.values();
+        for (MethodSignature signature : finalizedSignatures)
+        {
+            resultingMethods.remove(signatureMethodMap.get(signature));
+        }
+        return resultingMethods.toArray(new Method[resultingMethods.size()]);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyFactory.java b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyFactory.java
index 43691a0..56d574e 100644
--- a/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyFactory.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyFactory.java
@@ -1,103 +1,103 @@
-/*

- * 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.proxy2.impl;

-

-import org.apache.commons.proxy2.Interceptor;

-import org.apache.commons.proxy2.Invoker;

-import org.apache.commons.proxy2.ObjectProvider;

-import org.apache.commons.proxy2.ProxyFactory;

-

-/**

- * Base abstract {@link ProxyFactory} implementation, primarily providing implementations of the interface methods that

- * are typically convenience constructs over the other methods.

- */

-public abstract class AbstractProxyFactory implements ProxyFactory

-{

-    /**

-     * Returns true if all <code>proxyClasses</code> are interfaces.

-     * 

-     * @param proxyClasses

-     *            the proxy classes

-     * @return true if all <code>proxyClasses</code> are interfaces

-     */

-    @Override

-    public boolean canProxy(Class<?>... proxyClasses)

-    {

-        for (Class<?> proxyClass : proxyClasses)

-        {

-            if (!proxyClass.isInterface())

-            {

-                return false;

-            }

-        }

-        return true;

-    }

-

-    /**

-     * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>. The proxy will be

-     * generated using the current thread's "context class loader."

-     * 

-     * @param delegateProvider

-     *            the delegate provider

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement

-     * @return a proxy which delegates to the object provided by the target object provider

-     */

-    @Override

-    public <T> T createDelegatorProxy(ObjectProvider<?> delegateProvider, Class<?>... proxyClasses)

-    {

-        return createDelegatorProxy(Thread.currentThread().getContextClassLoader(), delegateProvider, proxyClasses);

-    }

-

-    /**

-     * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the

-     * <code>target</code> object. The proxy will be generated using the current thread's "context class loader."

-     * 

-     * @param target

-     *            the target object

-     * @param interceptor

-     *            the method interceptor

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement

-     * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the

-     *         <code>target</code> object.

-     */

-    @Override

-    public <T> T createInterceptorProxy(Object target, Interceptor interceptor, Class<?>... proxyClasses)

-    {

-        return createInterceptorProxy(Thread.currentThread().getContextClassLoader(), target, interceptor,

-                proxyClasses);

-    }

-

-    /**

-     * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations. The proxy will be

-     * generated using the current thread's "context class loader."

-     * 

-     * @param invoker

-     *            the invoker

-     * @param proxyClasses

-     *            the interfaces that the proxy should implement

-     * @return a proxy which uses the provided {@link Invoker} to handle all method invocations

-     */

-    @Override

-    public <T> T createInvokerProxy(Invoker invoker, Class<?>... proxyClasses)

-    {

-        return createInvokerProxy(Thread.currentThread().getContextClassLoader(), invoker, proxyClasses);

-    }

-

-}

+/*
+ * 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.proxy2.impl;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyFactory;
+
+/**
+ * Base abstract {@link ProxyFactory} implementation, primarily providing implementations of the interface methods that
+ * are typically convenience constructs over the other methods.
+ */
+public abstract class AbstractProxyFactory implements ProxyFactory
+{
+    /**
+     * Returns true if all <code>proxyClasses</code> are interfaces.
+     * 
+     * @param proxyClasses
+     *            the proxy classes
+     * @return true if all <code>proxyClasses</code> are interfaces
+     */
+    @Override
+    public boolean canProxy(Class<?>... proxyClasses)
+    {
+        for (Class<?> proxyClass : proxyClasses)
+        {
+            if (!proxyClass.isInterface())
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>. The proxy will be
+     * generated using the current thread's "context class loader."
+     * 
+     * @param delegateProvider
+     *            the delegate provider
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement
+     * @return a proxy which delegates to the object provided by the target object provider
+     */
+    @Override
+    public <T> T createDelegatorProxy(ObjectProvider<?> delegateProvider, Class<?>... proxyClasses)
+    {
+        return createDelegatorProxy(Thread.currentThread().getContextClassLoader(), delegateProvider, proxyClasses);
+    }
+
+    /**
+     * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+     * <code>target</code> object. The proxy will be generated using the current thread's "context class loader."
+     * 
+     * @param target
+     *            the target object
+     * @param interceptor
+     *            the method interceptor
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement
+     * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+     *         <code>target</code> object.
+     */
+    @Override
+    public <T> T createInterceptorProxy(Object target, Interceptor interceptor, Class<?>... proxyClasses)
+    {
+        return createInterceptorProxy(Thread.currentThread().getContextClassLoader(), target, interceptor,
+                proxyClasses);
+    }
+
+    /**
+     * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations. The proxy will be
+     * generated using the current thread's "context class loader."
+     * 
+     * @param invoker
+     *            the invoker
+     * @param proxyClasses
+     *            the interfaces that the proxy should implement
+     * @return a proxy which uses the provided {@link Invoker} to handle all method invocations
+     */
+    @Override
+    public <T> T createInvokerProxy(Invoker invoker, Class<?>... proxyClasses)
+    {
+        return createInvokerProxy(Thread.currentThread().getContextClassLoader(), invoker, proxyClasses);
+    }
+
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/impl/AbstractSubclassingProxyFactory.java b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractSubclassingProxyFactory.java
index b76b2cf..3090393 100644
--- a/core/src/main/java/org/apache/commons/proxy2/impl/AbstractSubclassingProxyFactory.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractSubclassingProxyFactory.java
@@ -1,161 +1,161 @@
-/*

- * 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.proxy2.impl;

-

-import java.io.Serializable;

-import java.lang.reflect.Constructor;

-import java.lang.reflect.Modifier;

-import java.util.LinkedHashSet;

-import java.util.Set;

-

-import org.apache.commons.proxy2.exception.ProxyFactoryException;

-

-/**

- * Parent {@link AbstractProxyFactory} for implementations that permit the generation of proxies with a specific

- * inheritance hierarchy.

- */

-public abstract class AbstractSubclassingProxyFactory extends AbstractProxyFactory

-{

-    //******************************************************************************************************************

-    // ProxyFactory Implementation

-    //******************************************************************************************************************

-

-    /**

-     * Returns true if a suitable superclass can be found, given the desired <code>proxyClasses</code>.

-     * 

-     * @param proxyClasses

-     *            the proxy classes

-     * @return true if a suitable superclass can be found, given the desired <code>proxyClasses</code>

-     */

-    @Override

-    public boolean canProxy(Class<?>... proxyClasses)

-    {

-        try

-        {

-            getSuperclass(proxyClasses);

-            return true;

-        }

-        catch (ProxyFactoryException e)

-        {

-            return false;

-        }

-    }

-

-    //******************************************************************************************************************

-    // Other Methods

-    //******************************************************************************************************************

-

-    private static boolean hasSuitableDefaultConstructor(Class<?> superclass)

-    {

-        final Constructor<?>[] declaredConstructors = superclass.getDeclaredConstructors();

-        for (int i = 0; i < declaredConstructors.length; i++)

-        {

-            Constructor<?> constructor = declaredConstructors[i];

-            if (constructor.getParameterTypes().length == 0

-                    && (Modifier.isPublic(constructor.getModifiers()) || Modifier.isProtected(constructor

-                            .getModifiers())))

-            {

-                return true;

-            }

-        }

-        return false;

-    }

-

-    private static Class<?>[] toNonInterfaces(Class<?>[] proxyClasses)

-    {

-        final Set<Class<?>> superclasses = new LinkedHashSet<Class<?>>();

-        for (Class<?> proxyClass : proxyClasses)

-        {

-            if (!proxyClass.isInterface())

-            {

-                superclasses.add(proxyClass);

-            }

-        }

-        return superclasses.toArray(new Class[superclasses.size()]);

-    }

-

-    /**

-     * Returns the <code>proxyClasses</code> transformed into an array of only the interface classes.

-     * <p/>

-     * <b>Note</b>: This class will append {@link Serializable} to the end of the list if it's not found!

-     * 

-     * @param proxyClasses

-     *            the proxy classes

-     * @return the <code>proxyClasses</code> transformed into an array of only the interface classes

-     */

-    protected static Class<?>[] toInterfaces(Class<?>[] proxyClasses)

-    {

-        final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();

-        for (Class<?> proxyClass : proxyClasses)

-        {

-            if (proxyClass.isInterface())

-            {

-                interfaces.add(proxyClass);

-            }

-        }

-        interfaces.add(Serializable.class);

-        return interfaces.toArray(new Class[interfaces.size()]);

-    }

-

-    /**

-     * Returns either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface

-     * class from <code>proxyClasses</code>.

-     * 

-     * @param proxyClasses

-     *            the proxy classes

-     * @return either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface

-     *         class from <code>proxyClasses</code>

-     * @throws ProxyFactoryException

-     *             if multiple non-interface classes are contained in <code>proxyClasses</code> or any of the

-     *             non-interface classes are final

-     */

-    public static Class<?> getSuperclass(Class<?>[] proxyClasses)

-    {

-        final Class<?>[] superclasses = toNonInterfaces(proxyClasses);

-        switch (superclasses.length)

-        {

-        case 0:

-            return Object.class;

-        case 1:

-            final Class<?> superclass = superclasses[0];

-            if (Modifier.isFinal(superclass.getModifiers()))

-            {

-                throw new ProxyFactoryException("Proxy class cannot extend " + superclass.getName()

-                        + " as it is final.");

-            }

-            if (!hasSuitableDefaultConstructor(superclass))

-            {

-                throw new ProxyFactoryException("Proxy class cannot extend " + superclass.getName()

-                        + ", because it has no visible \"default\" constructor.");

-            }

-            return superclass;

-        default:

-            final StringBuilder errorMessage = new StringBuilder("Proxy class cannot extend ");

-            for (int i = 0; i < superclasses.length; i++)

-            {

-                Class<?> c = superclasses[i];

-                errorMessage.append(c.getName());

-                if (i != superclasses.length - 1)

-                {

-                    errorMessage.append(", ");

-                }

-            }

-            errorMessage.append("; multiple inheritance not allowed.");

-            throw new ProxyFactoryException(errorMessage.toString());

-        }

-    }

-}

+/*
+ * 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.proxy2.impl;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.commons.proxy2.exception.ProxyFactoryException;
+
+/**
+ * Parent {@link AbstractProxyFactory} for implementations that permit the generation of proxies with a specific
+ * inheritance hierarchy.
+ */
+public abstract class AbstractSubclassingProxyFactory extends AbstractProxyFactory
+{
+    //******************************************************************************************************************
+    // ProxyFactory Implementation
+    //******************************************************************************************************************
+
+    /**
+     * Returns true if a suitable superclass can be found, given the desired <code>proxyClasses</code>.
+     * 
+     * @param proxyClasses
+     *            the proxy classes
+     * @return true if a suitable superclass can be found, given the desired <code>proxyClasses</code>
+     */
+    @Override
+    public boolean canProxy(Class<?>... proxyClasses)
+    {
+        try
+        {
+            getSuperclass(proxyClasses);
+            return true;
+        }
+        catch (ProxyFactoryException e)
+        {
+            return false;
+        }
+    }
+
+    //******************************************************************************************************************
+    // Other Methods
+    //******************************************************************************************************************
+
+    private static boolean hasSuitableDefaultConstructor(Class<?> superclass)
+    {
+        final Constructor<?>[] declaredConstructors = superclass.getDeclaredConstructors();
+        for (int i = 0; i < declaredConstructors.length; i++)
+        {
+            Constructor<?> constructor = declaredConstructors[i];
+            if (constructor.getParameterTypes().length == 0
+                    && (Modifier.isPublic(constructor.getModifiers()) || Modifier.isProtected(constructor
+                            .getModifiers())))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static Class<?>[] toNonInterfaces(Class<?>[] proxyClasses)
+    {
+        final Set<Class<?>> superclasses = new LinkedHashSet<Class<?>>();
+        for (Class<?> proxyClass : proxyClasses)
+        {
+            if (!proxyClass.isInterface())
+            {
+                superclasses.add(proxyClass);
+            }
+        }
+        return superclasses.toArray(new Class[superclasses.size()]);
+    }
+
+    /**
+     * Returns the <code>proxyClasses</code> transformed into an array of only the interface classes.
+     * <p/>
+     * <b>Note</b>: This class will append {@link Serializable} to the end of the list if it's not found!
+     * 
+     * @param proxyClasses
+     *            the proxy classes
+     * @return the <code>proxyClasses</code> transformed into an array of only the interface classes
+     */
+    protected static Class<?>[] toInterfaces(Class<?>[] proxyClasses)
+    {
+        final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
+        for (Class<?> proxyClass : proxyClasses)
+        {
+            if (proxyClass.isInterface())
+            {
+                interfaces.add(proxyClass);
+            }
+        }
+        interfaces.add(Serializable.class);
+        return interfaces.toArray(new Class[interfaces.size()]);
+    }
+
+    /**
+     * Returns either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface
+     * class from <code>proxyClasses</code>.
+     * 
+     * @param proxyClasses
+     *            the proxy classes
+     * @return either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface
+     *         class from <code>proxyClasses</code>
+     * @throws ProxyFactoryException
+     *             if multiple non-interface classes are contained in <code>proxyClasses</code> or any of the
+     *             non-interface classes are final
+     */
+    public static Class<?> getSuperclass(Class<?>[] proxyClasses)
+    {
+        final Class<?>[] superclasses = toNonInterfaces(proxyClasses);
+        switch (superclasses.length)
+        {
+        case 0:
+            return Object.class;
+        case 1:
+            final Class<?> superclass = superclasses[0];
+            if (Modifier.isFinal(superclass.getModifiers()))
+            {
+                throw new ProxyFactoryException("Proxy class cannot extend " + superclass.getName()
+                        + " as it is final.");
+            }
+            if (!hasSuitableDefaultConstructor(superclass))
+            {
+                throw new ProxyFactoryException("Proxy class cannot extend " + superclass.getName()
+                        + ", because it has no visible \"default\" constructor.");
+            }
+            return superclass;
+        default:
+            final StringBuilder errorMessage = new StringBuilder("Proxy class cannot extend ");
+            for (int i = 0; i < superclasses.length; i++)
+            {
+                Class<?> c = superclasses[i];
+                errorMessage.append(c.getName());
+                if (i != superclasses.length - 1)
+                {
+                    errorMessage.append(", ");
+                }
+            }
+            errorMessage.append("; multiple inheritance not allowed.");
+            throw new ProxyFactoryException(errorMessage.toString());
+        }
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/impl/MethodSignature.java b/core/src/main/java/org/apache/commons/proxy2/impl/MethodSignature.java
index 4c06c94..56679d4 100644
--- a/core/src/main/java/org/apache/commons/proxy2/impl/MethodSignature.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/MethodSignature.java
@@ -1,273 +1,273 @@
-/*

- * 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.proxy2.impl;

-

-import java.io.Serializable;

-import java.lang.reflect.Array;

-import java.lang.reflect.Method;

-import java.text.ParsePosition;

-import java.util.ArrayList;

-import java.util.Collections;

-import java.util.HashMap;

-import java.util.List;

-import java.util.Map;

-

-import org.apache.commons.lang3.ArrayUtils;

-import org.apache.commons.lang3.StringUtils;

-import org.apache.commons.lang3.Validate;

-import org.apache.commons.lang3.builder.HashCodeBuilder;

-import org.apache.commons.lang3.reflect.MethodUtils;

-import org.apache.commons.lang3.tuple.Pair;

-

-/**

- * A class for capturing the signature of a method (its name and parameter types).

- * 

- * @since 1.0

- */

-public class MethodSignature implements Serializable

-{

-    private static final long serialVersionUID = 1L;

-

-    private static final Map<Class<?>, Character> PRIMITIVE_ABBREVIATIONS;

-    private static final Map<Character, Class<?>> REVERSE_ABBREVIATIONS;

-    static

-    {

-        final Map<Class<?>, Character> primitiveAbbreviations = new HashMap<Class<?>, Character>();

-        primitiveAbbreviations.put(Boolean.TYPE, Character.valueOf('Z'));

-        primitiveAbbreviations.put(Byte.TYPE, Character.valueOf('B'));

-        primitiveAbbreviations.put(Short.TYPE, Character.valueOf('S'));

-        primitiveAbbreviations.put(Integer.TYPE, Character.valueOf('I'));

-        primitiveAbbreviations.put(Character.TYPE, Character.valueOf('C'));

-        primitiveAbbreviations.put(Long.TYPE, Character.valueOf('J'));

-        primitiveAbbreviations.put(Float.TYPE, Character.valueOf('F'));

-        primitiveAbbreviations.put(Double.TYPE, Character.valueOf('D'));

-        primitiveAbbreviations.put(Void.TYPE, Character.valueOf('V'));

-        final Map<Character, Class<?>> reverseAbbreviations = new HashMap<Character, Class<?>>();

-        for (Map.Entry<Class<?>, Character> e : primitiveAbbreviations.entrySet())

-        {

-            reverseAbbreviations.put(e.getValue(), e.getKey());

-        }

-        PRIMITIVE_ABBREVIATIONS = Collections.unmodifiableMap(primitiveAbbreviations);

-        REVERSE_ABBREVIATIONS = Collections.unmodifiableMap(reverseAbbreviations);

-    }

-

-    private static void appendTo(StringBuilder buf, Class<?> type)

-    {

-        if (type.isPrimitive())

-        {

-            buf.append(PRIMITIVE_ABBREVIATIONS.get(type));

-        }

-        else if (type.isArray())

-        {

-            buf.append('[');

-            appendTo(buf, type.getComponentType());

-        }

-        else

-        {

-            buf.append('L').append(type.getName().replace('.', '/')).append(';');

-        }

-    }

-

-    private static class SignaturePosition extends ParsePosition

-    {

-        SignaturePosition()

-        {

-            super(0);

-        }

-

-        SignaturePosition next()

-        {

-            return plus(1);

-        }

-

-        SignaturePosition plus(int addend)

-        {

-            setIndex(getIndex() + addend);

-            return this;

-        }

-    }

-

-    private static Pair<String, Class<?>[]> parse(String internal)

-    {

-        Validate.notBlank(internal, "Cannot parse blank method signature");

-        final SignaturePosition pos = new SignaturePosition();

-        int lparen = internal.indexOf('(', pos.getIndex());

-        Validate.isTrue(lparen > 0, "Method signature \"%s\" requires parentheses", internal);

-        final String name = internal.substring(0, lparen).trim();

-        Validate.notBlank(name, "Method signature \"%s\" has blank name", internal);

-

-        pos.setIndex(lparen + 1);

-

-        boolean complete = false;

-        final List<Class<?>> params = new ArrayList<Class<?>>();

-        while (pos.getIndex() < internal.length())

-        {

-            final char c = internal.charAt(pos.getIndex());

-            if (Character.isWhitespace(c))

-            {

-                pos.next();

-                continue;

-            }

-            final Character k = Character.valueOf(c);

-            if (REVERSE_ABBREVIATIONS.containsKey(k))

-            {

-                params.add(REVERSE_ABBREVIATIONS.get(k));

-                pos.next();

-                continue;

-            }

-            if (')' == c)

-            {

-                complete = true;

-                pos.next();

-                break;

-            }

-            try

-            {

-                params.add(parseType(internal, pos));

-            }

-            catch (ClassNotFoundException e)

-            {

-                throw new IllegalArgumentException(String.format("Method signature \"%s\" references unknown type",

-                        internal), e);

-            }

-        }

-        Validate.isTrue(complete, "Method signature \"%s\" is incomplete", internal);

-        Validate.isTrue(StringUtils.isBlank(internal.substring(pos.getIndex())),

-                "Method signature \"%s\" includes unrecognized content beyond end", internal);

-

-        return Pair.of(name, params.toArray(ArrayUtils.EMPTY_CLASS_ARRAY));

-    }

-

-    private static Class<?> parseType(String internal, SignaturePosition pos) throws ClassNotFoundException

-    {

-        final int here = pos.getIndex();

-        final char c = internal.charAt(here);

-

-        switch (c)

-        {

-        case '[':

-            pos.next();

-            final Class<?> componentType = parseType(internal, pos);

-            return Array.newInstance(componentType, 0).getClass();

-        case 'L':

-            pos.next();

-            final int type = pos.getIndex();

-            final int semi = internal.indexOf(';', type);

-            Validate.isTrue(semi > 0, "Type at index %d of method signature \"%s\" not terminated by semicolon",

-                    Integer.valueOf(here), internal);

-            final String className = internal.substring(type, semi).replace('/', '.');

-            Validate.notBlank(className, "Invalid classname at position %d of method signature \"%s\"",

-                    Integer.valueOf(type), internal);

-            pos.setIndex(semi + 1);

-            return Class.forName(className);

-        default:

-            throw new IllegalArgumentException(String.format(

-                    "Unexpected character at index %d of method signature \"%s\"",

-                    Integer.valueOf(here), internal));

-        }

-    }

-

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    /**

-     * Stored as a Java method descriptor minus return type.

-     */

-    private final String internal;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new MethodSignature instance.

-     * 

-     * @param method

-     */

-    public MethodSignature(Method method)

-    {

-        final StringBuilder buf = new StringBuilder(method.getName()).append('(');

-        for (Class<?> p : method.getParameterTypes())

-        {

-            appendTo(buf, p);

-        }

-        buf.append(')');

-        this.internal = buf.toString();

-    }

-

-    //******************************************************************************************************************

-    // Methods

-    //******************************************************************************************************************

-

-    /**

-     * Get the corresponding {@link Method} instance from the specified {@link Class}.

-     * 

-     * @param type

-     * @return Method

-     */

-    public Method toMethod(Class<?> type)

-    {

-        final Pair<String, Class<?>[]> info = parse(internal);

-        return MethodUtils.getAccessibleMethod(type, info.getLeft(), info.getRight());

-    }

-

-    //******************************************************************************************************************

-    // Canonical Methods

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public boolean equals(Object o)

-    {

-        if (o == null)

-        {

-            return false;

-        }

-        if (o == this)

-        {

-            return true;

-        }

-        if (o.getClass() != getClass())

-        {

-            return false;

-        }

-        MethodSignature other = (MethodSignature) o;

-        return other.internal.equals(internal);

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public int hashCode()

-    {

-        return new HashCodeBuilder().append(internal).build().intValue();

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public String toString()

-    {

-        return internal;

-    }

-}

+/*
+ * 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.proxy2.impl;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.text.ParsePosition;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.reflect.MethodUtils;
+import org.apache.commons.lang3.tuple.Pair;
+
+/**
+ * A class for capturing the signature of a method (its name and parameter types).
+ * 
+ * @since 1.0
+ */
+public class MethodSignature implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    private static final Map<Class<?>, Character> PRIMITIVE_ABBREVIATIONS;
+    private static final Map<Character, Class<?>> REVERSE_ABBREVIATIONS;
+    static
+    {
+        final Map<Class<?>, Character> primitiveAbbreviations = new HashMap<Class<?>, Character>();
+        primitiveAbbreviations.put(Boolean.TYPE, Character.valueOf('Z'));
+        primitiveAbbreviations.put(Byte.TYPE, Character.valueOf('B'));
+        primitiveAbbreviations.put(Short.TYPE, Character.valueOf('S'));
+        primitiveAbbreviations.put(Integer.TYPE, Character.valueOf('I'));
+        primitiveAbbreviations.put(Character.TYPE, Character.valueOf('C'));
+        primitiveAbbreviations.put(Long.TYPE, Character.valueOf('J'));
+        primitiveAbbreviations.put(Float.TYPE, Character.valueOf('F'));
+        primitiveAbbreviations.put(Double.TYPE, Character.valueOf('D'));
+        primitiveAbbreviations.put(Void.TYPE, Character.valueOf('V'));
+        final Map<Character, Class<?>> reverseAbbreviations = new HashMap<Character, Class<?>>();
+        for (Map.Entry<Class<?>, Character> e : primitiveAbbreviations.entrySet())
+        {
+            reverseAbbreviations.put(e.getValue(), e.getKey());
+        }
+        PRIMITIVE_ABBREVIATIONS = Collections.unmodifiableMap(primitiveAbbreviations);
+        REVERSE_ABBREVIATIONS = Collections.unmodifiableMap(reverseAbbreviations);
+    }
+
+    private static void appendTo(StringBuilder buf, Class<?> type)
+    {
+        if (type.isPrimitive())
+        {
+            buf.append(PRIMITIVE_ABBREVIATIONS.get(type));
+        }
+        else if (type.isArray())
+        {
+            buf.append('[');
+            appendTo(buf, type.getComponentType());
+        }
+        else
+        {
+            buf.append('L').append(type.getName().replace('.', '/')).append(';');
+        }
+    }
+
+    private static class SignaturePosition extends ParsePosition
+    {
+        SignaturePosition()
+        {
+            super(0);
+        }
+
+        SignaturePosition next()
+        {
+            return plus(1);
+        }
+
+        SignaturePosition plus(int addend)
+        {
+            setIndex(getIndex() + addend);
+            return this;
+        }
+    }
+
+    private static Pair<String, Class<?>[]> parse(String internal)
+    {
+        Validate.notBlank(internal, "Cannot parse blank method signature");
+        final SignaturePosition pos = new SignaturePosition();
+        int lparen = internal.indexOf('(', pos.getIndex());
+        Validate.isTrue(lparen > 0, "Method signature \"%s\" requires parentheses", internal);
+        final String name = internal.substring(0, lparen).trim();
+        Validate.notBlank(name, "Method signature \"%s\" has blank name", internal);
+
+        pos.setIndex(lparen + 1);
+
+        boolean complete = false;
+        final List<Class<?>> params = new ArrayList<Class<?>>();
+        while (pos.getIndex() < internal.length())
+        {
+            final char c = internal.charAt(pos.getIndex());
+            if (Character.isWhitespace(c))
+            {
+                pos.next();
+                continue;
+            }
+            final Character k = Character.valueOf(c);
+            if (REVERSE_ABBREVIATIONS.containsKey(k))
+            {
+                params.add(REVERSE_ABBREVIATIONS.get(k));
+                pos.next();
+                continue;
+            }
+            if (')' == c)
+            {
+                complete = true;
+                pos.next();
+                break;
+            }
+            try
+            {
+                params.add(parseType(internal, pos));
+            }
+            catch (ClassNotFoundException e)
+            {
+                throw new IllegalArgumentException(String.format("Method signature \"%s\" references unknown type",
+                        internal), e);
+            }
+        }
+        Validate.isTrue(complete, "Method signature \"%s\" is incomplete", internal);
+        Validate.isTrue(StringUtils.isBlank(internal.substring(pos.getIndex())),
+                "Method signature \"%s\" includes unrecognized content beyond end", internal);
+
+        return Pair.of(name, params.toArray(ArrayUtils.EMPTY_CLASS_ARRAY));
+    }
+
+    private static Class<?> parseType(String internal, SignaturePosition pos) throws ClassNotFoundException
+    {
+        final int here = pos.getIndex();
+        final char c = internal.charAt(here);
+
+        switch (c)
+        {
+        case '[':
+            pos.next();
+            final Class<?> componentType = parseType(internal, pos);
+            return Array.newInstance(componentType, 0).getClass();
+        case 'L':
+            pos.next();
+            final int type = pos.getIndex();
+            final int semi = internal.indexOf(';', type);
+            Validate.isTrue(semi > 0, "Type at index %d of method signature \"%s\" not terminated by semicolon",
+                    Integer.valueOf(here), internal);
+            final String className = internal.substring(type, semi).replace('/', '.');
+            Validate.notBlank(className, "Invalid classname at position %d of method signature \"%s\"",
+                    Integer.valueOf(type), internal);
+            pos.setIndex(semi + 1);
+            return Class.forName(className);
+        default:
+            throw new IllegalArgumentException(String.format(
+                    "Unexpected character at index %d of method signature \"%s\"",
+                    Integer.valueOf(here), internal));
+        }
+    }
+
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    /**
+     * Stored as a Java method descriptor minus return type.
+     */
+    private final String internal;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new MethodSignature instance.
+     * 
+     * @param method
+     */
+    public MethodSignature(Method method)
+    {
+        final StringBuilder buf = new StringBuilder(method.getName()).append('(');
+        for (Class<?> p : method.getParameterTypes())
+        {
+            appendTo(buf, p);
+        }
+        buf.append(')');
+        this.internal = buf.toString();
+    }
+
+    //******************************************************************************************************************
+    // Methods
+    //******************************************************************************************************************
+
+    /**
+     * Get the corresponding {@link Method} instance from the specified {@link Class}.
+     * 
+     * @param type
+     * @return Method
+     */
+    public Method toMethod(Class<?> type)
+    {
+        final Pair<String, Class<?>[]> info = parse(internal);
+        return MethodUtils.getAccessibleMethod(type, info.getLeft(), info.getRight());
+    }
+
+    //******************************************************************************************************************
+    // Canonical Methods
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o == null)
+        {
+            return false;
+        }
+        if (o == this)
+        {
+            return true;
+        }
+        if (o.getClass() != getClass())
+        {
+            return false;
+        }
+        MethodSignature other = (MethodSignature) o;
+        return other.internal.equals(internal);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        return new HashCodeBuilder().append(internal).build().intValue();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString()
+    {
+        return internal;
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassCache.java b/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassCache.java
index 5c20bdd..fbc64c2 100644
--- a/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassCache.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassCache.java
@@ -1,117 +1,117 @@
-/*

- * 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.proxy2.impl;

-

-import java.lang.ref.Reference;

-import java.lang.ref.WeakReference;

-import java.util.Arrays;

-import java.util.HashMap;

-import java.util.HashSet;

-import java.util.Map;

-import java.util.Set;

-import java.util.WeakHashMap;

-

-/**

- * A cache for storing implementation classes for proxies based on a specific type of {@link ProxyClassGenerator}. A

- * proxy class cache ensures that there is only one class for every {@link ProxyClassGenerator}/{@link ClassLoader}

- * /proxy class array combination.

- * 

- * @since 1.0

- */

-public class ProxyClassCache

-{

-

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private final Map<ClassLoader, Map<Set<Class<?>>, WeakReference<Class<?>>>> loaderToClassCache

-        = new WeakHashMap<ClassLoader, Map<Set<Class<?>>, WeakReference<Class<?>>>>();

-    private final ProxyClassGenerator proxyClassGenerator;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new ProxyClassCache instance.

-     * 

-     * @param proxyClassGenerator

-     */

-    public ProxyClassCache(ProxyClassGenerator proxyClassGenerator)

-    {

-        this.proxyClassGenerator = proxyClassGenerator;

-    }

-

-    //******************************************************************************************************************

-    // Other Methods

-    //******************************************************************************************************************

-

-    private Map<Set<Class<?>>, WeakReference<Class<?>>> getClassCache(ClassLoader classLoader)

-    {

-        Map<Set<Class<?>>, WeakReference<Class<?>>> cache = loaderToClassCache.get(classLoader);

-        if (cache == null)

-        {

-            cache = new HashMap<Set<Class<?>>, WeakReference<Class<?>>>();

-            loaderToClassCache.put(classLoader, cache);

-        }

-        return cache;

-    }

-

-    private Set<Class<?>> toClassCacheKey(Class<?>[] proxyClasses)

-    {

-        return new HashSet<Class<?>>(Arrays.asList(proxyClasses));

-    }

-

-    /**

-     * Returns the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and

-     * array of proxy classes.

-     * 

-     * @param classLoader

-     *            the classloader

-     * @param proxyClasses

-     *            the proxy classes

-     * @return the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and

-     *         array of proxy classes

-     */

-    public synchronized Class<?> getProxyClass(ClassLoader classLoader, Class<?>[] proxyClasses)

-    {

-        final Map<Set<Class<?>>, WeakReference<Class<?>>> classCache = getClassCache(classLoader);

-        final Set<Class<?>> key = toClassCacheKey(proxyClasses);

-        Class<?> proxyClass;

-        Reference<Class<?>> proxyClassReference = classCache.get(key);

-        if (proxyClassReference == null)

-        {

-            proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);

-            classCache.put(key, new WeakReference<Class<?>>(proxyClass));

-        }

-        else

-        {

-            synchronized (proxyClassReference)

-            {

-                proxyClass = proxyClassReference.get();

-                if (proxyClass == null)

-                {

-                    proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);

-                    classCache.put(key, new WeakReference<Class<?>>(proxyClass));

-                }

-            }

-        }

-        return proxyClass;

-    }

-}

+/*
+ * 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.proxy2.impl;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+/**
+ * A cache for storing implementation classes for proxies based on a specific type of {@link ProxyClassGenerator}. A
+ * proxy class cache ensures that there is only one class for every {@link ProxyClassGenerator}/{@link ClassLoader}
+ * /proxy class array combination.
+ * 
+ * @since 1.0
+ */
+public class ProxyClassCache
+{
+
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private final Map<ClassLoader, Map<Set<Class<?>>, WeakReference<Class<?>>>> loaderToClassCache
+        = new WeakHashMap<ClassLoader, Map<Set<Class<?>>, WeakReference<Class<?>>>>();
+    private final ProxyClassGenerator proxyClassGenerator;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new ProxyClassCache instance.
+     * 
+     * @param proxyClassGenerator
+     */
+    public ProxyClassCache(ProxyClassGenerator proxyClassGenerator)
+    {
+        this.proxyClassGenerator = proxyClassGenerator;
+    }
+
+    //******************************************************************************************************************
+    // Other Methods
+    //******************************************************************************************************************
+
+    private Map<Set<Class<?>>, WeakReference<Class<?>>> getClassCache(ClassLoader classLoader)
+    {
+        Map<Set<Class<?>>, WeakReference<Class<?>>> cache = loaderToClassCache.get(classLoader);
+        if (cache == null)
+        {
+            cache = new HashMap<Set<Class<?>>, WeakReference<Class<?>>>();
+            loaderToClassCache.put(classLoader, cache);
+        }
+        return cache;
+    }
+
+    private Set<Class<?>> toClassCacheKey(Class<?>[] proxyClasses)
+    {
+        return new HashSet<Class<?>>(Arrays.asList(proxyClasses));
+    }
+
+    /**
+     * Returns the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and
+     * array of proxy classes.
+     * 
+     * @param classLoader
+     *            the classloader
+     * @param proxyClasses
+     *            the proxy classes
+     * @return the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and
+     *         array of proxy classes
+     */
+    public synchronized Class<?> getProxyClass(ClassLoader classLoader, Class<?>[] proxyClasses)
+    {
+        final Map<Set<Class<?>>, WeakReference<Class<?>>> classCache = getClassCache(classLoader);
+        final Set<Class<?>> key = toClassCacheKey(proxyClasses);
+        Class<?> proxyClass;
+        Reference<Class<?>> proxyClassReference = classCache.get(key);
+        if (proxyClassReference == null)
+        {
+            proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);
+            classCache.put(key, new WeakReference<Class<?>>(proxyClass));
+        }
+        else
+        {
+            synchronized (proxyClassReference)
+            {
+                proxyClass = proxyClassReference.get();
+                if (proxyClass == null)
+                {
+                    proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);
+                    classCache.put(key, new WeakReference<Class<?>>(proxyClass));
+                }
+            }
+        }
+        return proxyClass;
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassGenerator.java b/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassGenerator.java
index 8de1238..7bdc7c0 100644
--- a/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassGenerator.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassGenerator.java
@@ -1,44 +1,44 @@
-/*

- * 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.proxy2.impl;

-

-/**

- * A proxy class generator generates Class instances for a given combination of interfaces in a given classloader.

- * Typically, in the context of a {@link org.apache.commons.proxy2.ProxyFactory} implementation, an instance will

- * generate proxy class instances for a specific type of proxies (interceptor, invoker, etc.) and will be associated

- * with a corresponding {@link ProxyClassCache}.

- * 

- * @since 1.0

- */

-public interface ProxyClassGenerator

-{

-    //******************************************************************************************************************

-    // Other Methods

-    //******************************************************************************************************************

-

-    /**

-     * Generates a proxy class for the supplied {@link ClassLoader} and proxy classes.

-     * 

-     * @param classLoader

-     *            the classloader

-     * @param proxyClasses

-     *            the proxy classes

-     * @return the dynamically generated proxy class

-     */

-    Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses);

-}

+/*
+ * 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.proxy2.impl;
+
+/**
+ * A proxy class generator generates Class instances for a given combination of interfaces in a given classloader.
+ * Typically, in the context of a {@link org.apache.commons.proxy2.ProxyFactory} implementation, an instance will
+ * generate proxy class instances for a specific type of proxies (interceptor, invoker, etc.) and will be associated
+ * with a corresponding {@link ProxyClassCache}.
+ * 
+ * @since 1.0
+ */
+public interface ProxyClassGenerator
+{
+    //******************************************************************************************************************
+    // Other Methods
+    //******************************************************************************************************************
+
+    /**
+     * Generates a proxy class for the supplied {@link ClassLoader} and proxy classes.
+     * 
+     * @param classLoader
+     *            the classloader
+     * @param proxyClasses
+     *            the proxy classes
+     * @return the dynamically generated proxy class
+     */
+    Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses);
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/invoker/DuckTypingInvoker.java b/core/src/main/java/org/apache/commons/proxy2/invoker/DuckTypingInvoker.java
index ad29119..c7a2236 100644
--- a/core/src/main/java/org/apache/commons/proxy2/invoker/DuckTypingInvoker.java
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/DuckTypingInvoker.java
@@ -1,108 +1,108 @@
-/*

- * 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.proxy2.invoker;

-

-import java.lang.reflect.Method;

-

-import org.apache.commons.proxy2.Invoker;

-import org.apache.commons.proxy2.ObjectProvider;

-

-/**

- * An invoker which supports <a href="http://en.wikipedia.org/wiki/Duck_typing">&quot;duck typing&quot;</a>, meaning

- * that it finds a matching method on the object returned from the target provider and invokes it. This class is useful

- * for adapting an existing class to an interface it does not implement.

- * <p>

- * <b>Example:</b>

- * </p>

- * <p>

- * 

- * <pre>

- * public class LegacyDuck // Does not implement interface!

- * {

- *   public void quack()

- *   {

- *     // Quacking logic...

- *   }

- * }

- * <p/>

- * public interface Duck

- * {

- *   public void quack();

- * }

- * <p/>

- * ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck()); // Always returns a "legacy" duck

- * DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);

- * Duck duck = ( Duck )proxyFactory.createInvokerProxy( invoker, new Class[] { Duck.class } );

- * </pre>

- * 

- * </p>

- */

-public class DuckTypingInvoker implements Invoker

-{

-    /** Serialization version */

-    private static final long serialVersionUID = 1L;

-

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private final ObjectProvider<?> targetProvider;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new DuckTypingInvoker instance.

-     * 

-     * @param targetProvider

-     */

-    public DuckTypingInvoker(final ObjectProvider<?> targetProvider)

-    {

-        this.targetProvider = targetProvider;

-    }

-

-    //******************************************************************************************************************

-    // Invoker Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public Object invoke(final Object proxy, final Method method, final Object[] arguments) throws Throwable

-    {

-        final Object target = targetProvider.getObject();

-        final Class<?> targetClass = target.getClass();

-        try

-        {

-            final Method targetMethod = targetClass.getMethod(method.getName(), method.getParameterTypes());

-            if (method.getReturnType().isAssignableFrom(targetMethod.getReturnType()))

-            {

-                return targetMethod.invoke(target, arguments);

-            }

-            throw new UnsupportedOperationException("Target type " + targetClass.getName()

-                    + " method has incompatible return type.");

-        }

-        catch (NoSuchMethodException e)

-        {

-            throw new UnsupportedOperationException("Target type " + targetClass.getName()

-                    + " does not have a method matching " + method + ".", e);

-        }

-    }

-}

+/*
+ * 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.proxy2.invoker;
+
+import java.lang.reflect.Method;
+
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+
+/**
+ * An invoker which supports <a href="http://en.wikipedia.org/wiki/Duck_typing">&quot;duck typing&quot;</a>, meaning
+ * that it finds a matching method on the object returned from the target provider and invokes it. This class is useful
+ * for adapting an existing class to an interface it does not implement.
+ * <p>
+ * <b>Example:</b>
+ * </p>
+ * <p>
+ * 
+ * <pre>
+ * public class LegacyDuck // Does not implement interface!
+ * {
+ *   public void quack()
+ *   {
+ *     // Quacking logic...
+ *   }
+ * }
+ * <p/>
+ * public interface Duck
+ * {
+ *   public void quack();
+ * }
+ * <p/>
+ * ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck()); // Always returns a "legacy" duck
+ * DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
+ * Duck duck = ( Duck )proxyFactory.createInvokerProxy( invoker, new Class[] { Duck.class } );
+ * </pre>
+ * 
+ * </p>
+ */
+public class DuckTypingInvoker implements Invoker
+{
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private final ObjectProvider<?> targetProvider;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new DuckTypingInvoker instance.
+     * 
+     * @param targetProvider
+     */
+    public DuckTypingInvoker(final ObjectProvider<?> targetProvider)
+    {
+        this.targetProvider = targetProvider;
+    }
+
+    //******************************************************************************************************************
+    // Invoker Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object invoke(final Object proxy, final Method method, final Object[] arguments) throws Throwable
+    {
+        final Object target = targetProvider.getObject();
+        final Class<?> targetClass = target.getClass();
+        try
+        {
+            final Method targetMethod = targetClass.getMethod(method.getName(), method.getParameterTypes());
+            if (method.getReturnType().isAssignableFrom(targetMethod.getReturnType()))
+            {
+                return targetMethod.invoke(target, arguments);
+            }
+            throw new UnsupportedOperationException("Target type " + targetClass.getName()
+                    + " method has incompatible return type.");
+        }
+        catch (NoSuchMethodException e)
+        {
+            throw new UnsupportedOperationException("Target type " + targetClass.getName()
+                    + " does not have a method matching " + method + ".", e);
+        }
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/invoker/InvocationHandlerAdapter.java b/core/src/main/java/org/apache/commons/proxy2/invoker/InvocationHandlerAdapter.java
index 0ec7f09..0b27d5b 100644
--- a/core/src/main/java/org/apache/commons/proxy2/invoker/InvocationHandlerAdapter.java
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/InvocationHandlerAdapter.java
@@ -1,67 +1,67 @@
-/*

- * 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.proxy2.invoker;

-

-import java.lang.reflect.InvocationHandler;

-import java.lang.reflect.Method;

-

-import org.apache.commons.proxy2.Invoker;

-

-/**

- * An adapter class to adapt the JDK's {@link InvocationHandler} interface to Commons Proxy's {@link Invoker} interface.

- * 

- * @since 1.0

- */

-public class InvocationHandlerAdapter implements Invoker

-{

-    /** Serialization version */

-    private static final long serialVersionUID = 1L;

-

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private final InvocationHandler invocationHandler;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new InvocationHandlerAdapter instance.

-     * 

-     * @param invocationHandler

-     */

-    public InvocationHandlerAdapter(InvocationHandler invocationHandler)

-    {

-        this.invocationHandler = invocationHandler;

-    }

-

-    //******************************************************************************************************************

-    // Invoker Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable

-    {

-        return invocationHandler.invoke(proxy, method, arguments);

-    }

-}

+/*
+ * 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.proxy2.invoker;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import org.apache.commons.proxy2.Invoker;
+
+/**
+ * An adapter class to adapt the JDK's {@link InvocationHandler} interface to Commons Proxy's {@link Invoker} interface.
+ * 
+ * @since 1.0
+ */
+public class InvocationHandlerAdapter implements Invoker
+{
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private final InvocationHandler invocationHandler;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new InvocationHandlerAdapter instance.
+     * 
+     * @param invocationHandler
+     */
+    public InvocationHandlerAdapter(InvocationHandler invocationHandler)
+    {
+        this.invocationHandler = invocationHandler;
+    }
+
+    //******************************************************************************************************************
+    // Invoker Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable
+    {
+        return invocationHandler.invoke(proxy, method, arguments);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/invoker/NullInvoker.java b/core/src/main/java/org/apache/commons/proxy2/invoker/NullInvoker.java
index b01f7e1..ad6a75d 100644
--- a/core/src/main/java/org/apache/commons/proxy2/invoker/NullInvoker.java
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/NullInvoker.java
@@ -1,55 +1,55 @@
-/*

- * 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.proxy2.invoker;

-

-import java.io.Serializable;

-import java.lang.reflect.Method;

-

-import org.apache.commons.proxy2.Invoker;

-import org.apache.commons.proxy2.ProxyUtils;

-

-/**

- * An {@link Invoker} implementation which merely returns null for all method invocations. This class is useful for

- * scenarios where the "null object" design pattern is needed.

- * 

- * @since 1.0

- */

-public class NullInvoker implements Invoker, Serializable

-{

-    /** Serialization version */

-    private static final long serialVersionUID = 1L;

-

-    /**

-     * Statically available instance.

-     */

-    public static final NullInvoker INSTANCE = new NullInvoker();

-

-    //******************************************************************************************************************

-    // Invoker Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

-    {

-        final Class<?> returnType = method.getReturnType();

-        return ProxyUtils.nullValue(returnType);

-    }

-}

+/*
+ * 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.proxy2.invoker;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ProxyUtils;
+
+/**
+ * An {@link Invoker} implementation which merely returns null for all method invocations. This class is useful for
+ * scenarios where the "null object" design pattern is needed.
+ * 
+ * @since 1.0
+ */
+public class NullInvoker implements Invoker, Serializable
+{
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Statically available instance.
+     */
+    public static final NullInvoker INSTANCE = new NullInvoker();
+
+    //******************************************************************************************************************
+    // Invoker Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+    {
+        final Class<?> returnType = method.getReturnType();
+        return ProxyUtils.nullValue(returnType);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/invoker/RecordedInvocation.java b/core/src/main/java/org/apache/commons/proxy2/invoker/RecordedInvocation.java
index 1cb284d..03e25a9 100644
--- a/core/src/main/java/org/apache/commons/proxy2/invoker/RecordedInvocation.java
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/RecordedInvocation.java
@@ -1,149 +1,149 @@
-/*

- * 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.proxy2.invoker;

-

-import java.lang.reflect.Method;

-

-import org.apache.commons.lang3.ArrayUtils;

-import org.apache.commons.proxy2.ProxyUtils;

-

-/**

- * Detached representation of a method invocation.

- * 

- */

-public class RecordedInvocation

-{

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private final Method invokedMethod;

-    private final Object[] arguments;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new RecordedInvocation instance.

-     * 

-     * @param invokedMethod

-     * @param arguments

-     */

-    public RecordedInvocation(Method invokedMethod, Object[] arguments)

-    {

-        this.invokedMethod = invokedMethod;

-        this.arguments = ArrayUtils.nullToEmpty(ArrayUtils.clone(arguments));

-    }

-

-    //******************************************************************************************************************

-    // Getter/Setter Methods

-    //******************************************************************************************************************

-

-    /**

-     * Get the invokedMethod.

-     * 

-     * @return Method

-     */

-    public Method getInvokedMethod()

-    {

-        return invokedMethod;

-    }

-

-    //******************************************************************************************************************

-    // Canonical Methods

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public String toString()

-    {

-        StringBuilder buffer = new StringBuilder();

-        buffer.append(invokedMethod.getDeclaringClass().getName());

-        buffer.append(".");

-        buffer.append(invokedMethod.getName());

-        buffer.append("(");

-        int count = arguments.length;

-        for (int i = 0; i < count; i++)

-        {

-            Object arg = arguments[i];

-            if (i > 0)

-            {

-                buffer.append(", ");

-            }

-            convert(buffer, arg);

-        }

-        buffer.append(")");

-        return buffer.toString();

-    }

-

-    //******************************************************************************************************************

-    // Other Methods

-    //******************************************************************************************************************

-

-    /**

-     * Add a string representation of <code>input</code> to <code>buffer</code>.

-     * 

-     * @param buffer

-     * @param input

-     */

-    protected void convert(StringBuilder buffer, Object input)

-    {

-        if (input == null)

-        {

-            buffer.append("<null>");

-            return;

-        }

-

-        // Primitive types, and non-object arrays

-        // use toString().

-        if (!(input instanceof Object[]))

-        {

-            buffer.append(input.toString());

-            return;

-        }

-        buffer.append("(");

-        buffer.append(ProxyUtils.getJavaClassName(input.getClass()));

-        buffer.append("){");

-        Object[] array = (Object[]) input;

-        int count = array.length;

-        for (int i = 0; i < count; i++)

-        {

-            if (i > 0)

-            {

-                buffer.append(", ");

-            }

-            // We use convert() again, because it could be a multi-dimensional array

-            // where each element must be converted.

-            convert(buffer, array[i]);

-        }

-        buffer.append("}");

-    }

-

-    /**

-     * Get the arguments.

-     * 

-     * @return Object[]

-     */

-    public Object[] getArguments()

-    {

-        return ArrayUtils.clone(arguments);

-    }

-}

+/*
+ * 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.proxy2.invoker;
+
+import java.lang.reflect.Method;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.proxy2.ProxyUtils;
+
+/**
+ * Detached representation of a method invocation.
+ * 
+ */
+public class RecordedInvocation
+{
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private final Method invokedMethod;
+    private final Object[] arguments;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new RecordedInvocation instance.
+     * 
+     * @param invokedMethod
+     * @param arguments
+     */
+    public RecordedInvocation(Method invokedMethod, Object[] arguments)
+    {
+        this.invokedMethod = invokedMethod;
+        this.arguments = ArrayUtils.nullToEmpty(ArrayUtils.clone(arguments));
+    }
+
+    //******************************************************************************************************************
+    // Getter/Setter Methods
+    //******************************************************************************************************************
+
+    /**
+     * Get the invokedMethod.
+     * 
+     * @return Method
+     */
+    public Method getInvokedMethod()
+    {
+        return invokedMethod;
+    }
+
+    //******************************************************************************************************************
+    // Canonical Methods
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString()
+    {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(invokedMethod.getDeclaringClass().getName());
+        buffer.append(".");
+        buffer.append(invokedMethod.getName());
+        buffer.append("(");
+        int count = arguments.length;
+        for (int i = 0; i < count; i++)
+        {
+            Object arg = arguments[i];
+            if (i > 0)
+            {
+                buffer.append(", ");
+            }
+            convert(buffer, arg);
+        }
+        buffer.append(")");
+        return buffer.toString();
+    }
+
+    //******************************************************************************************************************
+    // Other Methods
+    //******************************************************************************************************************
+
+    /**
+     * Add a string representation of <code>input</code> to <code>buffer</code>.
+     * 
+     * @param buffer
+     * @param input
+     */
+    protected void convert(StringBuilder buffer, Object input)
+    {
+        if (input == null)
+        {
+            buffer.append("<null>");
+            return;
+        }
+
+        // Primitive types, and non-object arrays
+        // use toString().
+        if (!(input instanceof Object[]))
+        {
+            buffer.append(input.toString());
+            return;
+        }
+        buffer.append("(");
+        buffer.append(ProxyUtils.getJavaClassName(input.getClass()));
+        buffer.append("){");
+        Object[] array = (Object[]) input;
+        int count = array.length;
+        for (int i = 0; i < count; i++)
+        {
+            if (i > 0)
+            {
+                buffer.append(", ");
+            }
+            // We use convert() again, because it could be a multi-dimensional array
+            // where each element must be converted.
+            convert(buffer, array[i]);
+        }
+        buffer.append("}");
+    }
+
+    /**
+     * Get the arguments.
+     * 
+     * @return Object[]
+     */
+    public Object[] getArguments()
+    {
+        return ArrayUtils.clone(arguments);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/invoker/recorder/InvocationRecorder.java b/core/src/main/java/org/apache/commons/proxy2/invoker/recorder/InvocationRecorder.java
index c29118c..bf35cd9 100644
--- a/core/src/main/java/org/apache/commons/proxy2/invoker/recorder/InvocationRecorder.java
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/recorder/InvocationRecorder.java
@@ -1,122 +1,122 @@
-/*

- * 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.proxy2.invoker.recorder;

-

-import java.lang.reflect.Method;

-import java.lang.reflect.Type;

-import java.util.LinkedList;

-import java.util.List;

-

-import org.apache.commons.lang3.reflect.TypeUtils;

-import org.apache.commons.proxy2.Invoker;

-import org.apache.commons.proxy2.ProxyFactory;

-import org.apache.commons.proxy2.ProxyUtils;

-import org.apache.commons.proxy2.invoker.RecordedInvocation;

-

-/**

- * An {@link InvocationRecorder} records method invocations against its generated proxies.

- * 

- */

-public class InvocationRecorder

-{

-    private final ProxyFactory proxyFactory;

-    private final List<RecordedInvocation> recordedInvocations = new LinkedList<RecordedInvocation>();

-

-    /**

-     * Create a new InvocationRecorder instance.

-     * 

-     * @param proxyFactory

-     */

-    public InvocationRecorder(ProxyFactory proxyFactory)

-    {

-        this.proxyFactory = proxyFactory;

-    }

-

-    /**

-     * Get the invocations that have been recorded up to this point. The list is "live" and should not be modified.

-     * 

-     * @return {@link List} of {@link RecordedInvocation}

-     */

-    public List<RecordedInvocation> getRecordedInvocations()

-    {

-        return recordedInvocations;

-    }

-

-    /**

-     * Generate a recording proxy for the specified class.

-     * 

-     * @param <T>

-     * @param type

-     * @return the generated proxy

-     */

-    public <T> T proxy(Class<T> type)

-    {

-        return proxy(type, type);

-    }

-

-    /**

-     * Generate a recording proxy for the specified class, qualified as <code>genericType</code>.

-     * 

-     * @param <T>

-     * @param genericType

-     * @param type

-     * @return the generated proxy

-     */

-    public <T> T proxy(Type genericType, Class<T> type)

-    {

-        if (proxyFactory.canProxy(type))

-        {

-            return proxyFactory.<T> createInvokerProxy(new InvocationRecorderInvoker(genericType), type);

-        }

-        return ProxyUtils.nullValue(type);

-    }

-

-    private final class InvocationRecorderInvoker implements Invoker

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        private final Type targetType;

-

-        private InvocationRecorderInvoker(Type targetType)

-        {

-            this.targetType = targetType;

-        }

-

-        /**

-         * {@inheritDoc}

-         */

-        @Override

-        public Object invoke(Object o, Method method, Object[] args) throws Throwable

-        {

-            recordedInvocations.add(new RecordedInvocation(method, args));

-            final Class<?> returnType = TypeUtils.getRawType(method.getGenericReturnType(), targetType);

-            //what to do if returnType is null?

-            return proxy(method.getGenericReturnType(), returnType);

-        }

-    }

-

-    /**

-     * Reset this {@link InvocationRecorder}.

-     */

-    public void reset()

-    {

-        recordedInvocations.clear();

-    }

-

-}

+/*
+ * 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.proxy2.invoker.recorder;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.lang3.reflect.TypeUtils;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ProxyFactory;
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.invoker.RecordedInvocation;
+
+/**
+ * An {@link InvocationRecorder} records method invocations against its generated proxies.
+ * 
+ */
+public class InvocationRecorder
+{
+    private final ProxyFactory proxyFactory;
+    private final List<RecordedInvocation> recordedInvocations = new LinkedList<RecordedInvocation>();
+
+    /**
+     * Create a new InvocationRecorder instance.
+     * 
+     * @param proxyFactory
+     */
+    public InvocationRecorder(ProxyFactory proxyFactory)
+    {
+        this.proxyFactory = proxyFactory;
+    }
+
+    /**
+     * Get the invocations that have been recorded up to this point. The list is "live" and should not be modified.
+     * 
+     * @return {@link List} of {@link RecordedInvocation}
+     */
+    public List<RecordedInvocation> getRecordedInvocations()
+    {
+        return recordedInvocations;
+    }
+
+    /**
+     * Generate a recording proxy for the specified class.
+     * 
+     * @param <T>
+     * @param type
+     * @return the generated proxy
+     */
+    public <T> T proxy(Class<T> type)
+    {
+        return proxy(type, type);
+    }
+
+    /**
+     * Generate a recording proxy for the specified class, qualified as <code>genericType</code>.
+     * 
+     * @param <T>
+     * @param genericType
+     * @param type
+     * @return the generated proxy
+     */
+    public <T> T proxy(Type genericType, Class<T> type)
+    {
+        if (proxyFactory.canProxy(type))
+        {
+            return proxyFactory.<T> createInvokerProxy(new InvocationRecorderInvoker(genericType), type);
+        }
+        return ProxyUtils.nullValue(type);
+    }
+
+    private final class InvocationRecorderInvoker implements Invoker
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        private final Type targetType;
+
+        private InvocationRecorderInvoker(Type targetType)
+        {
+            this.targetType = targetType;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Object invoke(Object o, Method method, Object[] args) throws Throwable
+        {
+            recordedInvocations.add(new RecordedInvocation(method, args));
+            final Class<?> returnType = TypeUtils.getRawType(method.getGenericReturnType(), targetType);
+            //what to do if returnType is null?
+            return proxy(method.getGenericReturnType(), returnType);
+        }
+    }
+
+    /**
+     * Reset this {@link InvocationRecorder}.
+     */
+    public void reset()
+    {
+        recordedInvocations.clear();
+    }
+
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/BeanProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/BeanProvider.java
index 181d163..3639d9b 100644
--- a/core/src/main/java/org/apache/commons/proxy2/provider/BeanProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/BeanProvider.java
@@ -1,81 +1,81 @@
-/*

- * 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.proxy2.provider;

-

-import java.io.Serializable;

-

-import org.apache.commons.lang3.Validate;

-import org.apache.commons.proxy2.ObjectProvider;

-import org.apache.commons.proxy2.exception.ObjectProviderException;

-

-/**

- * Uses <code>Class.newInstance()</code> to instantiate an object.

- * 

- * @since 1.0

- */

-public class BeanProvider<T> implements ObjectProvider<T>, Serializable

-{

-    /** Serialization version */

-    private static final long serialVersionUID = 1L;

-

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private final Class<? extends T> beanClass;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Constructs a provider which instantiates objects of the specified bean class.

-     * 

-     * @param beanClass

-     *            the bean class

-     */

-    public BeanProvider(Class<? extends T> beanClass)

-    {

-        Validate.notNull(beanClass, "Bean class cannot be null.");

-        this.beanClass = beanClass;

-    }

-

-    //******************************************************************************************************************

-    // ObjectProvider Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public T getObject()

-    {

-        try

-        {

-            return beanClass.newInstance();

-        }

-        catch (InstantiationException e)

-        {

-            throw new ObjectProviderException(e, "%s is not concrete.", beanClass);

-        }

-        catch (IllegalAccessException e)

-        {

-            throw new ObjectProviderException(e, "Constructor for %s is not accessible.", beanClass);

-        }

-    }

-}

+/*
+ * 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.proxy2.provider;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.exception.ObjectProviderException;
+
+/**
+ * Uses <code>Class.newInstance()</code> to instantiate an object.
+ * 
+ * @since 1.0
+ */
+public class BeanProvider<T> implements ObjectProvider<T>, Serializable
+{
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private final Class<? extends T> beanClass;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Constructs a provider which instantiates objects of the specified bean class.
+     * 
+     * @param beanClass
+     *            the bean class
+     */
+    public BeanProvider(Class<? extends T> beanClass)
+    {
+        Validate.notNull(beanClass, "Bean class cannot be null.");
+        this.beanClass = beanClass;
+    }
+
+    //******************************************************************************************************************
+    // ObjectProvider Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public T getObject()
+    {
+        try
+        {
+            return beanClass.newInstance();
+        }
+        catch (InstantiationException e)
+        {
+            throw new ObjectProviderException(e, "%s is not concrete.", beanClass);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new ObjectProviderException(e, "Constructor for %s is not accessible.", beanClass);
+        }
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/CloningProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/CloningProvider.java
index fdcf7cd..1035bb9 100644
--- a/core/src/main/java/org/apache/commons/proxy2/provider/CloningProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/CloningProvider.java
@@ -1,84 +1,84 @@
-/*

- * 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.proxy2.provider;

-

-import java.io.Serializable;

-

-import org.apache.commons.lang3.ObjectUtils;

-import org.apache.commons.lang3.Validate;

-import org.apache.commons.lang3.exception.CloneFailedException;

-import org.apache.commons.lang3.reflect.MethodUtils;

-import org.apache.commons.proxy2.ObjectProvider;

-import org.apache.commons.proxy2.exception.ObjectProviderException;

-

-/**

- * Merely calls <code>clone()</code> (reflectively) on the given {@link Cloneable} object.

- * 

- * @since 1.0

- */

-public class CloningProvider<T extends Cloneable> implements ObjectProvider<T>, Serializable

-{

-    /**

-     * Serialization version

-     */

-    private static final long serialVersionUID = 1L;

-

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private final T cloneable;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Constructs a provider which returns clone copies of the specified {@link Cloneable} object.

-     * 

-     * @param cloneable

-     *            the object to clone

-     */

-    public CloningProvider(T cloneable)

-    {

-        Validate.notNull(cloneable, "Cloneable object cannot be null.");

-        Validate.isTrue(MethodUtils.getAccessibleMethod(cloneable.getClass(), "clone") != null,

-                String.format("Class %s does not override clone() method as public.", cloneable.getClass().getName()));

-        this.cloneable = cloneable;

-    }

-

-    //******************************************************************************************************************

-    // ObjectProvider Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public T getObject()

-    {

-        try

-        {

-            return ObjectUtils.clone(cloneable);

-        }

-        catch (CloneFailedException e) {

-            throw new ObjectProviderException(e.getMessage(), e.getCause());

-        }

-    }

-

-}

+/*
+ * 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.proxy2.provider;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.exception.CloneFailedException;
+import org.apache.commons.lang3.reflect.MethodUtils;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.exception.ObjectProviderException;
+
+/**
+ * Merely calls <code>clone()</code> (reflectively) on the given {@link Cloneable} object.
+ * 
+ * @since 1.0
+ */
+public class CloningProvider<T extends Cloneable> implements ObjectProvider<T>, Serializable
+{
+    /**
+     * Serialization version
+     */
+    private static final long serialVersionUID = 1L;
+
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private final T cloneable;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Constructs a provider which returns clone copies of the specified {@link Cloneable} object.
+     * 
+     * @param cloneable
+     *            the object to clone
+     */
+    public CloningProvider(T cloneable)
+    {
+        Validate.notNull(cloneable, "Cloneable object cannot be null.");
+        Validate.isTrue(MethodUtils.getAccessibleMethod(cloneable.getClass(), "clone") != null,
+                String.format("Class %s does not override clone() method as public.", cloneable.getClass().getName()));
+        this.cloneable = cloneable;
+    }
+
+    //******************************************************************************************************************
+    // ObjectProvider Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public T getObject()
+    {
+        try
+        {
+            return ObjectUtils.clone(cloneable);
+        }
+        catch (CloneFailedException e) {
+            throw new ObjectProviderException(e.getMessage(), e.getCause());
+        }
+    }
+
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/ConstantProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/ConstantProvider.java
index aa15f1e..c818f30 100644
--- a/core/src/main/java/org/apache/commons/proxy2/provider/ConstantProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/ConstantProvider.java
@@ -1,66 +1,66 @@
-/*

- * 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.proxy2.provider;

-

-import java.io.Serializable;

-

-import org.apache.commons.proxy2.ObjectProvider;

-

-/**

- * Always returns the same object.

- * 

- * @since 1.0

- */

-public class ConstantProvider<T> implements ObjectProvider<T>, Serializable

-{

-    /** Serialization version */

-    private static final long serialVersionUID = 1L;

-

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private final T constant;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new ConstantProvider instance.

-     * 

-     * @param constant

-     */

-    public ConstantProvider(T constant)

-    {

-        this.constant = constant;

-    }

-

-    //******************************************************************************************************************

-    // ObjectProvider Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public T getObject()

-    {

-        return constant;

-    }

-}   

+/*
+ * 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.proxy2.provider;
+
+import java.io.Serializable;
+
+import org.apache.commons.proxy2.ObjectProvider;
+
+/**
+ * Always returns the same object.
+ * 
+ * @since 1.0
+ */
+public class ConstantProvider<T> implements ObjectProvider<T>, Serializable
+{
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private final T constant;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new ConstantProvider instance.
+     * 
+     * @param constant
+     */
+    public ConstantProvider(T constant)
+    {
+        this.constant = constant;
+    }
+
+    //******************************************************************************************************************
+    // ObjectProvider Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public T getObject()
+    {
+        return constant;
+    }
+}   
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/NullProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/NullProvider.java
index 51d9ad7..0791d71 100644
--- a/core/src/main/java/org/apache/commons/proxy2/provider/NullProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/NullProvider.java
@@ -1,41 +1,41 @@
-/*

- * 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.proxy2.provider;

-

-/**

- * Always returns null.

- * 

- * @since 1.0

- */

-public class NullProvider<T> extends ConstantProvider<T>

-{

-    /** Serialization version */

-    private static final long serialVersionUID = 1L;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new NullProvider instance.

-     */

-    public NullProvider()

-    {

-        super(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.proxy2.provider;
+
+/**
+ * Always returns null.
+ * 
+ * @since 1.0
+ */
+public class NullProvider<T> extends ConstantProvider<T>
+{
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new NullProvider instance.
+     */
+    public NullProvider()
+    {
+        super(null);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/ProviderDecorator.java b/core/src/main/java/org/apache/commons/proxy2/provider/ProviderDecorator.java
index 4bfc144..2a214c8 100644
--- a/core/src/main/java/org/apache/commons/proxy2/provider/ProviderDecorator.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/ProviderDecorator.java
@@ -1,82 +1,82 @@
-/*

- * 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.proxy2.provider;

-

-import org.apache.commons.proxy2.ObjectProvider;

-

-/**

- * Returns the result of the inner {@link ObjectProvider provider}. Subclasses can override the {@link #getObject()}

- * method and decorate what comes back from the inner provider in some way (by {@link SingletonProvider caching it} for

- * example).

- * 

- * @since 1.0

- */

-public class ProviderDecorator<T> implements ObjectProvider<T>

-{

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private static final long serialVersionUID = 1L;

-

-    /**

-     * The wrapped {@link ObjectProvider}.

-     */

-    private ObjectProvider<? extends T> inner;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new ProviderDecorator instance.

-     * 

-     * @param inner

-     */

-    public ProviderDecorator(ObjectProvider<? extends T> inner)

-    {

-        this.inner = inner;

-    }

-

-    //******************************************************************************************************************

-    // ObjectProvider Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public T getObject()

-    {

-        return inner.getObject();

-    }

-

-    //******************************************************************************************************************

-    // Getter/Setter Methods

-    //******************************************************************************************************************

-

-    protected ObjectProvider<? extends T> getInner()

-    {

-        return inner;

-    }

-

-    public void setInner(ObjectProvider<? extends T> inner)

-    {

-        this.inner = inner;

-    }

-}

+/*
+ * 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.proxy2.provider;
+
+import org.apache.commons.proxy2.ObjectProvider;
+
+/**
+ * Returns the result of the inner {@link ObjectProvider provider}. Subclasses can override the {@link #getObject()}
+ * method and decorate what comes back from the inner provider in some way (by {@link SingletonProvider caching it} for
+ * example).
+ * 
+ * @since 1.0
+ */
+public class ProviderDecorator<T> implements ObjectProvider<T>
+{
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The wrapped {@link ObjectProvider}.
+     */
+    private ObjectProvider<? extends T> inner;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new ProviderDecorator instance.
+     * 
+     * @param inner
+     */
+    public ProviderDecorator(ObjectProvider<? extends T> inner)
+    {
+        this.inner = inner;
+    }
+
+    //******************************************************************************************************************
+    // ObjectProvider Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public T getObject()
+    {
+        return inner.getObject();
+    }
+
+    //******************************************************************************************************************
+    // Getter/Setter Methods
+    //******************************************************************************************************************
+
+    protected ObjectProvider<? extends T> getInner()
+    {
+        return inner;
+    }
+
+    public void setInner(ObjectProvider<? extends T> inner)
+    {
+        this.inner = inner;
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/SingletonProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/SingletonProvider.java
index 4638488..54a007b 100644
--- a/core/src/main/java/org/apache/commons/proxy2/provider/SingletonProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/SingletonProvider.java
@@ -1,73 +1,73 @@
-/*

- * 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.proxy2.provider;

-

-import org.apache.commons.proxy2.ObjectProvider;

-

-/**

- * Wraps another object provider, making sure to only call it once, returning the value returned from the wrapped

- * provider on all subsequent invocations.

- * 

- * @since 1.0

- */

-public class SingletonProvider<T> extends ProviderDecorator<T>

-{

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private static final long serialVersionUID = 1L;

-

-    private T instance;

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    /**

-     * Create a new SingletonProvider instance.

-     * 

-     * @param inner

-     */

-    public SingletonProvider(ObjectProvider<? extends T> inner)

-    {

-        super(inner);

-    }

-

-    //******************************************************************************************************************

-    // ObjectProvider Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public T getObject()

-    {

-        synchronized (this)

-        {

-            if (instance == null)

-            {

-                instance = super.getObject();

-                // Garbage collection

-                setInner(null);

-            }

-            return instance;

-        }

-    }

-}

+/*
+ * 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.proxy2.provider;
+
+import org.apache.commons.proxy2.ObjectProvider;
+
+/**
+ * Wraps another object provider, making sure to only call it once, returning the value returned from the wrapped
+ * provider on all subsequent invocations.
+ * 
+ * @since 1.0
+ */
+public class SingletonProvider<T> extends ProviderDecorator<T>
+{
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private static final long serialVersionUID = 1L;
+
+    private T instance;
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    /**
+     * Create a new SingletonProvider instance.
+     * 
+     * @param inner
+     */
+    public SingletonProvider(ObjectProvider<? extends T> inner)
+    {
+        super(inner);
+    }
+
+    //******************************************************************************************************************
+    // ObjectProvider Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public T getObject()
+    {
+        synchronized (this)
+        {
+            if (instance == null)
+            {
+                instance = super.getObject();
+                // Garbage collection
+                setInner(null);
+            }
+            return instance;
+        }
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/AbstractProxyFactoryTestCase.java b/core/src/test/java/org/apache/commons/proxy2/AbstractProxyFactoryTestCase.java
index d83b843..363addf 100644
--- a/core/src/test/java/org/apache/commons/proxy2/AbstractProxyFactoryTestCase.java
+++ b/core/src/test/java/org/apache/commons/proxy2/AbstractProxyFactoryTestCase.java
@@ -1,410 +1,410 @@
-/*

- * 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.proxy2;

-

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertFalse;

-import static org.junit.Assert.assertNotNull;

-import static org.junit.Assert.assertNotSame;

-import static org.junit.Assert.assertSame;

-import static org.junit.Assert.assertTrue;

-

-import java.io.IOException;

-import java.io.Serializable;

-import java.lang.reflect.Method;

-import java.util.Arrays;

-import java.util.Date;

-import java.util.Iterator;

-import java.util.LinkedList;

-import java.util.List;

-import java.util.ServiceLoader;

-import java.util.SortedSet;

-import java.util.TreeSet;

-

-import org.apache.commons.proxy2.provider.BeanProvider;

-import org.apache.commons.proxy2.provider.ConstantProvider;

-import org.apache.commons.proxy2.provider.SingletonProvider;

-import org.apache.commons.proxy2.util.AbstractTestCase;

-import org.apache.commons.proxy2.util.DuplicateEcho;

-import org.apache.commons.proxy2.util.Echo;

-import org.apache.commons.proxy2.util.EchoImpl;

-import org.apache.commons.proxy2.util.SuffixInterceptor;

-import org.junit.Test;

-

-@SuppressWarnings("serial")

-public abstract class AbstractProxyFactoryTestCase extends AbstractTestCase

-{

-    //**********************************************************************************************************************

-    // Fields

-    //**********************************************************************************************************************

-

-    private static final Class<?>[] ECHO_ONLY = new Class[] { Echo.class };

-    protected final ProxyFactory factory;

-    private static final Class<?>[] COMPARABLE_ONLY = new Class[] { Comparable.class };

-

-    //**********************************************************************************************************************

-    // Constructors

-    //**********************************************************************************************************************

-

-    protected AbstractProxyFactoryTestCase()

-    {

-        final ServiceLoader<ProxyFactory> serviceLoader = ServiceLoader.load(ProxyFactory.class);

-        Iterator<ProxyFactory> iter = serviceLoader.iterator();

-        if (iter.hasNext())

-        {

-            this.factory = iter.next();

-        }

-        else

-        {

-            throw new RuntimeException("Unable to find proxy factory implementation.");

-        }

-

-    }

-

-    //**********************************************************************************************************************

-    // Other Methods

-    //**********************************************************************************************************************

-

-    private ObjectProvider<Echo> createSingletonEcho()

-    {

-        return new SingletonProvider<Echo>(new BeanProvider<Echo>(EchoImpl.class));

-    }

-

-    @Test

-    public void testInterceptorHashCode()

-    {

-        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);

-        assertEquals(proxy.hashCode(), System.identityHashCode(proxy));

-    }

-

-    @Test

-    public void testInvokerHashCode() throws Exception

-    {

-        final Echo proxy = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);

-        assertEquals(proxy.hashCode(), System.identityHashCode(proxy));

-    }

-

-    @Test

-    public void testDelegatorHashCode() throws Exception

-    {

-        final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);

-        assertEquals(proxy.hashCode(), System.identityHashCode(proxy));

-    }

-

-    @Test

-    public void testInterceptorEquals()

-    {

-        final Date date = new Date();

-        final Comparable<?> proxy1 = factory.createInterceptorProxy(date, new NoOpMethodInterceptor(), COMPARABLE_ONLY);

-        final Comparable<?> proxy2 = factory.createInterceptorProxy(date, new NoOpMethodInterceptor(), COMPARABLE_ONLY);

-        assertEquals(proxy1, proxy1);

-        assertFalse(proxy1.equals(proxy2));

-        assertFalse(proxy2.equals(proxy1));

-    }

-

-    @Test

-    public void testInvokerEquals() throws Exception

-    {

-        final Comparable<?> proxy1 = factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);

-        final Comparable<?> proxy2 = factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);

-        assertEquals(proxy1, proxy1);

-        assertFalse(proxy1.equals(proxy2));

-        assertFalse(proxy2.equals(proxy1));

-    }

-

-    @Test

-    public void testDelegatorEquals() throws Exception

-    {

-        final Date date = new Date();

-        final Comparable<?> proxy1 = factory.createDelegatorProxy(new ConstantProvider<Date>(date), COMPARABLE_ONLY);

-        final Comparable<?> proxy2 = factory.createDelegatorProxy(new ConstantProvider<Date>(date), COMPARABLE_ONLY);

-        assertEquals(proxy1, proxy1);

-        assertFalse(proxy1.equals(proxy2));

-        assertFalse(proxy2.equals(proxy1));

-    }

-

-    @Test

-    public void testBooleanInterceptorParameter()

-    {

-        final Echo echo = factory.createInterceptorProxy(new EchoImpl(), new InterceptorTester(), ECHO_ONLY);

-        assertFalse(echo.echoBack(false));

-        assertTrue(echo.echoBack(true));

-    }

-

-    @Test

-    public void testCanProxy()

-    {

-        assertTrue(factory.canProxy(Echo.class));

-        assertFalse(factory.canProxy(EchoImpl.class));

-    }

-

-    @Test

-    public void testChangingArguments()

-    {

-        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new ChangeArgumentInterceptor(), ECHO_ONLY);

-        assertEquals("something different", proxy.echoBack("whatever"));

-    }

-

-    @Test

-    public void testCreateDelegatingProxy()

-    {

-        final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);

-        echo.echo();

-        assertEquals("message", echo.echoBack("message"));

-        assertEquals("ab", echo.echoBack("a", "b"));

-    }

-

-    @Test

-    public void testCreateInterceptorProxy()

-    {

-        final Echo target = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);

-        final Echo proxy = factory.createInterceptorProxy(target, new SuffixInterceptor(" suffix"), ECHO_ONLY);

-        proxy.echo();

-        assertEquals("message suffix", proxy.echoBack("message"));

-    }

-

-    @Test

-    public void testDelegatingProxyClassCaching() throws Exception

-    {

-        final Echo proxy1 = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);

-        final Echo proxy2 = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);

-        assertNotSame(proxy1, proxy2);

-        assertSame(proxy1.getClass(), proxy2.getClass());

-    }

-

-    @Test

-    public void testDelegatingProxyInterfaceOrder()

-    {

-        final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), Echo.class, DuplicateEcho.class);

-        final List<Class<?>> expected = new LinkedList<Class<?>>(Arrays.<Class<?>> asList(Echo.class,

-                DuplicateEcho.class));

-        final List<Class<?>> actual = new LinkedList<Class<?>>(Arrays.asList(echo.getClass().getInterfaces()));

-        actual.retainAll(expected); // Doesn't alter order!

-        assertEquals(expected, actual);

-    }

-

-    @Test

-    public void testDelegatingProxySerializable() throws Exception

-    {

-        final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);

-        assertSerializable(proxy);

-    }

-

-    @Test

-    public void testInterceptingProxyClassCaching() throws Exception

-    {

-        final Echo proxy1 = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);

-        final Echo proxy2 = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);

-        assertNotSame(proxy1, proxy2);

-        assertSame(proxy1.getClass(), proxy2.getClass());

-    }

-

-    @Test

-    public void testInterceptingProxySerializable() throws Exception

-    {

-        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);

-        assertSerializable(proxy);

-    }

-

-    @Test(expected = IOException.class)

-    public void testInterceptorProxyWithCheckedException() throws Exception

-    {

-        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);

-        proxy.ioException();

-    }

-

-    @Test(expected = IllegalArgumentException.class)

-    public void testInterceptorProxyWithUncheckedException() throws Exception

-    {

-        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);

-        proxy.illegalArgument();

-    }

-

-    @Test

-    public void testInterfaceHierarchies()

-    {

-        final SortedSet<String> set = factory.createDelegatorProxy(new ConstantProvider<SortedSet<String>>(

-                new TreeSet<String>()), SortedSet.class);

-        set.add("Hello");

-    }

-

-    @Test

-    public void testInvokerProxy() throws Exception

-    {

-        final InvokerTester tester = new InvokerTester();

-        final Echo echo = factory.createInvokerProxy(tester, ECHO_ONLY);

-        echo.echoBack("hello");

-        assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);

-        assertSame(echo, tester.proxy);

-        assertNotNull(tester.args);

-        assertEquals(1, tester.args.length);

-        assertEquals("hello", tester.args[0]);

-    }

-

-    @Test

-    public void testInvokerProxyClassCaching() throws Exception

-    {

-        final Echo proxy1 = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);

-        final Echo proxy2 = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);

-        assertNotSame(proxy1, proxy2);

-        assertSame(proxy1.getClass(), proxy2.getClass());

-    }

-

-    @Test

-    public void testInvokerProxySerializable() throws Exception

-    {

-        final Echo proxy = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);

-        assertSerializable(proxy);

-    }

-

-    @Test

-    public void testMethodInvocationClassCaching() throws Exception

-    {

-        final InterceptorTester tester = new InterceptorTester();

-        final EchoImpl target = new EchoImpl();

-        final Echo proxy1 = factory.createInterceptorProxy(target, tester, ECHO_ONLY);

-        final Echo proxy2 = factory.createInterceptorProxy(target, tester, Echo.class, DuplicateEcho.class);

-        proxy1.echoBack("hello1");

-        final Class<?> invocationClass1 = tester.invocationClass;

-        proxy2.echoBack("hello2");

-        assertSame(invocationClass1, tester.invocationClass);

-    }

-

-    @Test

-    public void testMethodInvocationDuplicateMethods() throws Exception

-    {

-        final InterceptorTester tester = new InterceptorTester();

-        final EchoImpl target = new EchoImpl();

-        final Echo proxy = factory.createInterceptorProxy(target, tester, Echo.class, DuplicateEcho.class);

-        proxy.echoBack("hello");

-        assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);

-    }

-

-    @Test

-    public void testMethodInvocationImplementation() throws Exception

-    {

-        final InterceptorTester tester = new InterceptorTester();

-        final EchoImpl target = new EchoImpl();

-        final Echo proxy = factory.createInterceptorProxy(target, tester, ECHO_ONLY);

-        proxy.echo();

-        assertNotNull(tester.arguments);

-        assertEquals(0, tester.arguments.length);

-        assertEquals(Echo.class.getMethod("echo"), tester.method);

-        assertSame(proxy, tester.proxy);

-        proxy.echoBack("Hello");

-        assertNotNull(tester.arguments);

-        assertEquals(1, tester.arguments.length);

-        assertEquals("Hello", tester.arguments[0]);

-        assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);

-        proxy.echoBack("Hello", "World");

-        assertNotNull(tester.arguments);

-        assertEquals(2, tester.arguments.length);

-        assertEquals("Hello", tester.arguments[0]);

-        assertEquals("World", tester.arguments[1]);

-        assertEquals(Echo.class.getMethod("echoBack", String.class, String.class), tester.method);

-    }

-

-    @Test

-    public void testPrimitiveParameter()

-    {

-        final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);

-        assertEquals(1, echo.echoBack(1));

-    }

-

-    @Test(expected = IOException.class)

-    public void testProxyWithCheckedException() throws Exception

-    {

-        final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);

-        proxy.ioException();

-    }

-

-    @Test(expected = IllegalArgumentException.class)

-    public void testProxyWithUncheckedException() throws Exception

-    {

-        final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);

-        proxy.illegalArgument();

-    }

-

-    @Test

-    public void testWithNonAccessibleTargetType()

-    {

-        final Echo proxy = factory.createInterceptorProxy(new PrivateEcho(), new NoOpMethodInterceptor(), ECHO_ONLY);

-        proxy.echo();

-    }

-

-    //**********************************************************************************************************************

-    // Inner Classes

-    //**********************************************************************************************************************

-

-    private static class ChangeArgumentInterceptor implements Interceptor

-    {

-        @Override

-        public Object intercept(Invocation methodInvocation) throws Throwable

-        {

-            methodInvocation.getArguments()[0] = "something different";

-            return methodInvocation.proceed();

-        }

-    }

-

-    protected static class InterceptorTester implements Interceptor

-    {

-        private Object[] arguments;

-        private Method method;

-        private Object proxy;

-        private Class<?> invocationClass;

-

-        @Override

-        public Object intercept(Invocation methodInvocation) throws Throwable

-        {

-            arguments = methodInvocation.getArguments();

-            method = methodInvocation.getMethod();

-            proxy = methodInvocation.getProxy();

-            invocationClass = methodInvocation.getClass();

-            return methodInvocation.proceed();

-        }

-    }

-

-    protected static class InvokerTester implements Invoker

-    {

-        private Object method;

-        private Object[] args;

-        private Object proxy;

-

-        @Override

-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

-        {

-            this.proxy = proxy;

-            this.method = method;

-            this.args = args;

-            return null;

-        }

-    }

-

-    protected static class NoOpMethodInterceptor implements Interceptor, Serializable

-    {

-        @Override

-        public Object intercept(Invocation methodInvocation) throws Throwable

-        {

-            return methodInvocation.proceed();

-        }

-    }

-

-    private static class PrivateEcho extends EchoImpl

-    {

-    }

-}

+/*
+ * 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.proxy2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.commons.proxy2.provider.BeanProvider;
+import org.apache.commons.proxy2.provider.ConstantProvider;
+import org.apache.commons.proxy2.provider.SingletonProvider;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.DuplicateEcho;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.EchoImpl;
+import org.apache.commons.proxy2.util.SuffixInterceptor;
+import org.junit.Test;
+
+@SuppressWarnings("serial")
+public abstract class AbstractProxyFactoryTestCase extends AbstractTestCase
+{
+    //**********************************************************************************************************************
+    // Fields
+    //**********************************************************************************************************************
+
+    private static final Class<?>[] ECHO_ONLY = new Class[] { Echo.class };
+    protected final ProxyFactory factory;
+    private static final Class<?>[] COMPARABLE_ONLY = new Class[] { Comparable.class };
+
+    //**********************************************************************************************************************
+    // Constructors
+    //**********************************************************************************************************************
+
+    protected AbstractProxyFactoryTestCase()
+    {
+        final ServiceLoader<ProxyFactory> serviceLoader = ServiceLoader.load(ProxyFactory.class);
+        Iterator<ProxyFactory> iter = serviceLoader.iterator();
+        if (iter.hasNext())
+        {
+            this.factory = iter.next();
+        }
+        else
+        {
+            throw new RuntimeException("Unable to find proxy factory implementation.");
+        }
+
+    }
+
+    //**********************************************************************************************************************
+    // Other Methods
+    //**********************************************************************************************************************
+
+    private ObjectProvider<Echo> createSingletonEcho()
+    {
+        return new SingletonProvider<Echo>(new BeanProvider<Echo>(EchoImpl.class));
+    }
+
+    @Test
+    public void testInterceptorHashCode()
+    {
+        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+        assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
+    }
+
+    @Test
+    public void testInvokerHashCode() throws Exception
+    {
+        final Echo proxy = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
+        assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
+    }
+
+    @Test
+    public void testDelegatorHashCode() throws Exception
+    {
+        final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+        assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
+    }
+
+    @Test
+    public void testInterceptorEquals()
+    {
+        final Date date = new Date();
+        final Comparable<?> proxy1 = factory.createInterceptorProxy(date, new NoOpMethodInterceptor(), COMPARABLE_ONLY);
+        final Comparable<?> proxy2 = factory.createInterceptorProxy(date, new NoOpMethodInterceptor(), COMPARABLE_ONLY);
+        assertEquals(proxy1, proxy1);
+        assertFalse(proxy1.equals(proxy2));
+        assertFalse(proxy2.equals(proxy1));
+    }
+
+    @Test
+    public void testInvokerEquals() throws Exception
+    {
+        final Comparable<?> proxy1 = factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);
+        final Comparable<?> proxy2 = factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);
+        assertEquals(proxy1, proxy1);
+        assertFalse(proxy1.equals(proxy2));
+        assertFalse(proxy2.equals(proxy1));
+    }
+
+    @Test
+    public void testDelegatorEquals() throws Exception
+    {
+        final Date date = new Date();
+        final Comparable<?> proxy1 = factory.createDelegatorProxy(new ConstantProvider<Date>(date), COMPARABLE_ONLY);
+        final Comparable<?> proxy2 = factory.createDelegatorProxy(new ConstantProvider<Date>(date), COMPARABLE_ONLY);
+        assertEquals(proxy1, proxy1);
+        assertFalse(proxy1.equals(proxy2));
+        assertFalse(proxy2.equals(proxy1));
+    }
+
+    @Test
+    public void testBooleanInterceptorParameter()
+    {
+        final Echo echo = factory.createInterceptorProxy(new EchoImpl(), new InterceptorTester(), ECHO_ONLY);
+        assertFalse(echo.echoBack(false));
+        assertTrue(echo.echoBack(true));
+    }
+
+    @Test
+    public void testCanProxy()
+    {
+        assertTrue(factory.canProxy(Echo.class));
+        assertFalse(factory.canProxy(EchoImpl.class));
+    }
+
+    @Test
+    public void testChangingArguments()
+    {
+        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new ChangeArgumentInterceptor(), ECHO_ONLY);
+        assertEquals("something different", proxy.echoBack("whatever"));
+    }
+
+    @Test
+    public void testCreateDelegatingProxy()
+    {
+        final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
+        echo.echo();
+        assertEquals("message", echo.echoBack("message"));
+        assertEquals("ab", echo.echoBack("a", "b"));
+    }
+
+    @Test
+    public void testCreateInterceptorProxy()
+    {
+        final Echo target = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
+        final Echo proxy = factory.createInterceptorProxy(target, new SuffixInterceptor(" suffix"), ECHO_ONLY);
+        proxy.echo();
+        assertEquals("message suffix", proxy.echoBack("message"));
+    }
+
+    @Test
+    public void testDelegatingProxyClassCaching() throws Exception
+    {
+        final Echo proxy1 = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+        final Echo proxy2 = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+        assertNotSame(proxy1, proxy2);
+        assertSame(proxy1.getClass(), proxy2.getClass());
+    }
+
+    @Test
+    public void testDelegatingProxyInterfaceOrder()
+    {
+        final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), Echo.class, DuplicateEcho.class);
+        final List<Class<?>> expected = new LinkedList<Class<?>>(Arrays.<Class<?>> asList(Echo.class,
+                DuplicateEcho.class));
+        final List<Class<?>> actual = new LinkedList<Class<?>>(Arrays.asList(echo.getClass().getInterfaces()));
+        actual.retainAll(expected); // Doesn't alter order!
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testDelegatingProxySerializable() throws Exception
+    {
+        final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+        assertSerializable(proxy);
+    }
+
+    @Test
+    public void testInterceptingProxyClassCaching() throws Exception
+    {
+        final Echo proxy1 = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+        final Echo proxy2 = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+        assertNotSame(proxy1, proxy2);
+        assertSame(proxy1.getClass(), proxy2.getClass());
+    }
+
+    @Test
+    public void testInterceptingProxySerializable() throws Exception
+    {
+        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+        assertSerializable(proxy);
+    }
+
+    @Test(expected = IOException.class)
+    public void testInterceptorProxyWithCheckedException() throws Exception
+    {
+        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+        proxy.ioException();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInterceptorProxyWithUncheckedException() throws Exception
+    {
+        final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+        proxy.illegalArgument();
+    }
+
+    @Test
+    public void testInterfaceHierarchies()
+    {
+        final SortedSet<String> set = factory.createDelegatorProxy(new ConstantProvider<SortedSet<String>>(
+                new TreeSet<String>()), SortedSet.class);
+        set.add("Hello");
+    }
+
+    @Test
+    public void testInvokerProxy() throws Exception
+    {
+        final InvokerTester tester = new InvokerTester();
+        final Echo echo = factory.createInvokerProxy(tester, ECHO_ONLY);
+        echo.echoBack("hello");
+        assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
+        assertSame(echo, tester.proxy);
+        assertNotNull(tester.args);
+        assertEquals(1, tester.args.length);
+        assertEquals("hello", tester.args[0]);
+    }
+
+    @Test
+    public void testInvokerProxyClassCaching() throws Exception
+    {
+        final Echo proxy1 = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
+        final Echo proxy2 = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
+        assertNotSame(proxy1, proxy2);
+        assertSame(proxy1.getClass(), proxy2.getClass());
+    }
+
+    @Test
+    public void testInvokerProxySerializable() throws Exception
+    {
+        final Echo proxy = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
+        assertSerializable(proxy);
+    }
+
+    @Test
+    public void testMethodInvocationClassCaching() throws Exception
+    {
+        final InterceptorTester tester = new InterceptorTester();
+        final EchoImpl target = new EchoImpl();
+        final Echo proxy1 = factory.createInterceptorProxy(target, tester, ECHO_ONLY);
+        final Echo proxy2 = factory.createInterceptorProxy(target, tester, Echo.class, DuplicateEcho.class);
+        proxy1.echoBack("hello1");
+        final Class<?> invocationClass1 = tester.invocationClass;
+        proxy2.echoBack("hello2");
+        assertSame(invocationClass1, tester.invocationClass);
+    }
+
+    @Test
+    public void testMethodInvocationDuplicateMethods() throws Exception
+    {
+        final InterceptorTester tester = new InterceptorTester();
+        final EchoImpl target = new EchoImpl();
+        final Echo proxy = factory.createInterceptorProxy(target, tester, Echo.class, DuplicateEcho.class);
+        proxy.echoBack("hello");
+        assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
+    }
+
+    @Test
+    public void testMethodInvocationImplementation() throws Exception
+    {
+        final InterceptorTester tester = new InterceptorTester();
+        final EchoImpl target = new EchoImpl();
+        final Echo proxy = factory.createInterceptorProxy(target, tester, ECHO_ONLY);
+        proxy.echo();
+        assertNotNull(tester.arguments);
+        assertEquals(0, tester.arguments.length);
+        assertEquals(Echo.class.getMethod("echo"), tester.method);
+        assertSame(proxy, tester.proxy);
+        proxy.echoBack("Hello");
+        assertNotNull(tester.arguments);
+        assertEquals(1, tester.arguments.length);
+        assertEquals("Hello", tester.arguments[0]);
+        assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
+        proxy.echoBack("Hello", "World");
+        assertNotNull(tester.arguments);
+        assertEquals(2, tester.arguments.length);
+        assertEquals("Hello", tester.arguments[0]);
+        assertEquals("World", tester.arguments[1]);
+        assertEquals(Echo.class.getMethod("echoBack", String.class, String.class), tester.method);
+    }
+
+    @Test
+    public void testPrimitiveParameter()
+    {
+        final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
+        assertEquals(1, echo.echoBack(1));
+    }
+
+    @Test(expected = IOException.class)
+    public void testProxyWithCheckedException() throws Exception
+    {
+        final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+        proxy.ioException();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testProxyWithUncheckedException() throws Exception
+    {
+        final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+        proxy.illegalArgument();
+    }
+
+    @Test
+    public void testWithNonAccessibleTargetType()
+    {
+        final Echo proxy = factory.createInterceptorProxy(new PrivateEcho(), new NoOpMethodInterceptor(), ECHO_ONLY);
+        proxy.echo();
+    }
+
+    //**********************************************************************************************************************
+    // Inner Classes
+    //**********************************************************************************************************************
+
+    private static class ChangeArgumentInterceptor implements Interceptor
+    {
+        @Override
+        public Object intercept(Invocation methodInvocation) throws Throwable
+        {
+            methodInvocation.getArguments()[0] = "something different";
+            return methodInvocation.proceed();
+        }
+    }
+
+    protected static class InterceptorTester implements Interceptor
+    {
+        private Object[] arguments;
+        private Method method;
+        private Object proxy;
+        private Class<?> invocationClass;
+
+        @Override
+        public Object intercept(Invocation methodInvocation) throws Throwable
+        {
+            arguments = methodInvocation.getArguments();
+            method = methodInvocation.getMethod();
+            proxy = methodInvocation.getProxy();
+            invocationClass = methodInvocation.getClass();
+            return methodInvocation.proceed();
+        }
+    }
+
+    protected static class InvokerTester implements Invoker
+    {
+        private Object method;
+        private Object[] args;
+        private Object proxy;
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+        {
+            this.proxy = proxy;
+            this.method = method;
+            this.args = args;
+            return null;
+        }
+    }
+
+    protected static class NoOpMethodInterceptor implements Interceptor, Serializable
+    {
+        @Override
+        public Object intercept(Invocation methodInvocation) throws Throwable
+        {
+            return methodInvocation.proceed();
+        }
+    }
+
+    private static class PrivateEcho extends EchoImpl
+    {
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/AbstractSubclassingProxyFactoryTestCase.java b/core/src/test/java/org/apache/commons/proxy2/AbstractSubclassingProxyFactoryTestCase.java
index b659c30..8cd7ff1 100644
--- a/core/src/test/java/org/apache/commons/proxy2/AbstractSubclassingProxyFactoryTestCase.java
+++ b/core/src/test/java/org/apache/commons/proxy2/AbstractSubclassingProxyFactoryTestCase.java
@@ -1,216 +1,216 @@
-/*

- * 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.proxy2;

-

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertFalse;

-import static org.junit.Assert.assertTrue;

-

-import java.util.Date;

-

-import org.apache.commons.proxy2.exception.ProxyFactoryException;

-import org.apache.commons.proxy2.invoker.NullInvoker;

-import org.apache.commons.proxy2.provider.ConstantProvider;

-import org.apache.commons.proxy2.util.AbstractEcho;

-import org.apache.commons.proxy2.util.Echo;

-import org.apache.commons.proxy2.util.EchoImpl;

-import org.junit.Test;

-

-@SuppressWarnings("serial")

-public abstract class AbstractSubclassingProxyFactoryTestCase extends AbstractProxyFactoryTestCase

-{

-    //----------------------------------------------------------------------------------------------------------------------

-    // Fields

-    //----------------------------------------------------------------------------------------------------------------------

-

-    private static final Class<?>[] DATE_ONLY = new Class[] { Date.class };

-

-    //----------------------------------------------------------------------------------------------------------------------

-    // Other Methods

-    //----------------------------------------------------------------------------------------------------------------------

-

-    @Override

-    @Test

-    public void testCanProxy()

-    {

-        assertTrue(factory.canProxy(new Class[] { Echo.class }));

-        assertTrue(factory.canProxy(new Class[] { EchoImpl.class }));

-        assertFalse(factory.canProxy(new Class[] { FinalEcho.class }));

-        assertTrue(factory.canProxy(new Class[] { FinalMethodEcho.class, Echo.class }));

-        assertFalse(factory.canProxy(new Class[] { NoDefaultConstructorEcho.class }));

-        assertTrue(factory.canProxy(new Class[] { ProtectedConstructorEcho.class }));

-        assertFalse(factory.canProxy(new Class[] { InvisibleEcho.class }));

-        assertFalse(factory.canProxy(new Class[] { Echo.class, EchoImpl.class, String.class }));

-    }

-

-    @Override

-    @Test

-    public void testDelegatorEquals() throws Exception

-    {

-        final EqualsEcho echo = new EqualsEcho("text");

-        final Echo proxy1 = factory.createDelegatorProxy(new ConstantProvider<Echo>(echo),

-                new Class[] { EqualsEcho.class });

-        final Echo proxy2 = factory.createDelegatorProxy(new ConstantProvider<Echo>(echo),

-                new Class[] { EqualsEcho.class });

-        assertEquals(proxy1, proxy1);

-        assertFalse(proxy1.equals(proxy2));

-        assertFalse(proxy2.equals(proxy1));

-    }

-

-    @Test(expected = ProxyFactoryException.class)

-    public void testDelegatorWithMultipleSuperclasses()

-    {

-        factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), new Class[] { EchoImpl.class,

-                String.class });

-    }

-

-    @Test

-    public void testDelegatorWithSuperclass()

-    {

-        final Echo echo = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), new Class[] {

-                Echo.class, EchoImpl.class });

-        assertTrue(echo instanceof EchoImpl);

-    }

-

-    @Override

-    @Test

-    public void testInterceptorEquals()

-    {

-        final EqualsEcho echo = new EqualsEcho("text");

-        final Echo proxy1 = factory.createInterceptorProxy(echo, new NoOpMethodInterceptor(),

-                new Class[] { EqualsEcho.class });

-        final Echo proxy2 = factory.createInterceptorProxy(echo, new NoOpMethodInterceptor(),

-                new Class[] { EqualsEcho.class });

-        assertEquals(proxy1, proxy1);

-        assertFalse(proxy1.equals(proxy2));

-        assertFalse(proxy2.equals(proxy1));

-    }

-

-    @Test(expected = ProxyFactoryException.class)

-    public void testInterceptorWithMultipleSuperclasses()

-    {

-        factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), new Class[] { EchoImpl.class,

-                String.class });

-    }

-

-    @Test

-    public void testInterceptorWithSuperclass()

-    {

-        final Echo echo = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), new Class[] {

-                Echo.class, EchoImpl.class });

-        assertTrue(echo instanceof EchoImpl);

-    }

-

-    @Test(expected = ProxyFactoryException.class)

-    public void testInvocationHandlerWithMultipleSuperclasses()

-    {

-        factory.createInvokerProxy(new NullInvoker(), new Class[] { EchoImpl.class, String.class });

-    }

-

-    @Override

-    @Test

-    public void testInvokerEquals() throws Exception

-    {

-        final Date proxy1 = factory.createInvokerProxy(new InvokerTester(), DATE_ONLY);

-        final Date proxy2 = factory.createInvokerProxy(new InvokerTester(), DATE_ONLY);

-        assertEquals(proxy1, proxy1);

-        assertFalse(proxy1.equals(proxy2));

-        assertFalse(proxy2.equals(proxy1));

-    }

-

-    @Test

-    public void testInvokerWithSuperclass()

-    {

-        final Echo echo = factory.createInvokerProxy(new NullInvoker(), new Class[] { Echo.class, EchoImpl.class });

-        assertTrue(echo instanceof EchoImpl);

-    }

-

-    @Test

-    public void testProxiesWithClashingFinalMethodInSuperclass()

-    {

-        final Class<?>[] proxyClasses = new Class[] { Echo.class, FinalMethodEcho.class };

-        Echo proxy = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), proxyClasses);

-        assertEquals("final", proxy.echoBack("echo"));

-

-        proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), proxyClasses);

-        assertEquals("final", proxy.echoBack("echo"));

-

-        proxy = factory.createInvokerProxy(new NullInvoker(), proxyClasses);

-        assertEquals("final", proxy.echoBack("echo"));

-    }

-

-    @Test

-    public void testWithAbstractSuperclass()

-    {

-        final Echo echo = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()),

-                new Class[] { AbstractEcho.class });

-        assertEquals("hello", echo.echoBack("hello"));

-        assertEquals("helloworld", echo.echoBack("hello", "world"));

-    }

-

-    //----------------------------------------------------------------------------------------------------------------------

-    // Inner Classes

-    //----------------------------------------------------------------------------------------------------------------------

-

-    public static class EqualsEcho extends EchoImpl

-    {

-        @SuppressWarnings("unused")

-        private final String text;

-

-        protected EqualsEcho()

-        {

-            this("testing");

-        }

-

-        public EqualsEcho(String text)

-        {

-            this.text = text;

-        }

-    }

-

-    public static final class FinalEcho extends EchoImpl

-    {

-    }

-

-    public static class FinalMethodEcho extends EchoImpl

-    {

-        @Override

-        public final String echoBack(String message)

-        {

-            return "final";

-        }

-    }

-

-    private static class InvisibleEcho extends EchoImpl

-    {

-    }

-

-    public static class NoDefaultConstructorEcho extends EchoImpl

-    {

-        public NoDefaultConstructorEcho(String param)

-        {

-        }

-    }

-

-    public static class ProtectedConstructorEcho extends EchoImpl

-    {

-        protected ProtectedConstructorEcho()

-        {

-        }

-    }

-}

+/*
+ * 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.proxy2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+
+import org.apache.commons.proxy2.exception.ProxyFactoryException;
+import org.apache.commons.proxy2.invoker.NullInvoker;
+import org.apache.commons.proxy2.provider.ConstantProvider;
+import org.apache.commons.proxy2.util.AbstractEcho;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.EchoImpl;
+import org.junit.Test;
+
+@SuppressWarnings("serial")
+public abstract class AbstractSubclassingProxyFactoryTestCase extends AbstractProxyFactoryTestCase
+{
+    //----------------------------------------------------------------------------------------------------------------------
+    // Fields
+    //----------------------------------------------------------------------------------------------------------------------
+
+    private static final Class<?>[] DATE_ONLY = new Class[] { Date.class };
+
+    //----------------------------------------------------------------------------------------------------------------------
+    // Other Methods
+    //----------------------------------------------------------------------------------------------------------------------
+
+    @Override
+    @Test
+    public void testCanProxy()
+    {
+        assertTrue(factory.canProxy(new Class[] { Echo.class }));
+        assertTrue(factory.canProxy(new Class[] { EchoImpl.class }));
+        assertFalse(factory.canProxy(new Class[] { FinalEcho.class }));
+        assertTrue(factory.canProxy(new Class[] { FinalMethodEcho.class, Echo.class }));
+        assertFalse(factory.canProxy(new Class[] { NoDefaultConstructorEcho.class }));
+        assertTrue(factory.canProxy(new Class[] { ProtectedConstructorEcho.class }));
+        assertFalse(factory.canProxy(new Class[] { InvisibleEcho.class }));
+        assertFalse(factory.canProxy(new Class[] { Echo.class, EchoImpl.class, String.class }));
+    }
+
+    @Override
+    @Test
+    public void testDelegatorEquals() throws Exception
+    {
+        final EqualsEcho echo = new EqualsEcho("text");
+        final Echo proxy1 = factory.createDelegatorProxy(new ConstantProvider<Echo>(echo),
+                new Class[] { EqualsEcho.class });
+        final Echo proxy2 = factory.createDelegatorProxy(new ConstantProvider<Echo>(echo),
+                new Class[] { EqualsEcho.class });
+        assertEquals(proxy1, proxy1);
+        assertFalse(proxy1.equals(proxy2));
+        assertFalse(proxy2.equals(proxy1));
+    }
+
+    @Test(expected = ProxyFactoryException.class)
+    public void testDelegatorWithMultipleSuperclasses()
+    {
+        factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), new Class[] { EchoImpl.class,
+                String.class });
+    }
+
+    @Test
+    public void testDelegatorWithSuperclass()
+    {
+        final Echo echo = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), new Class[] {
+                Echo.class, EchoImpl.class });
+        assertTrue(echo instanceof EchoImpl);
+    }
+
+    @Override
+    @Test
+    public void testInterceptorEquals()
+    {
+        final EqualsEcho echo = new EqualsEcho("text");
+        final Echo proxy1 = factory.createInterceptorProxy(echo, new NoOpMethodInterceptor(),
+                new Class[] { EqualsEcho.class });
+        final Echo proxy2 = factory.createInterceptorProxy(echo, new NoOpMethodInterceptor(),
+                new Class[] { EqualsEcho.class });
+        assertEquals(proxy1, proxy1);
+        assertFalse(proxy1.equals(proxy2));
+        assertFalse(proxy2.equals(proxy1));
+    }
+
+    @Test(expected = ProxyFactoryException.class)
+    public void testInterceptorWithMultipleSuperclasses()
+    {
+        factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), new Class[] { EchoImpl.class,
+                String.class });
+    }
+
+    @Test
+    public void testInterceptorWithSuperclass()
+    {
+        final Echo echo = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), new Class[] {
+                Echo.class, EchoImpl.class });
+        assertTrue(echo instanceof EchoImpl);
+    }
+
+    @Test(expected = ProxyFactoryException.class)
+    public void testInvocationHandlerWithMultipleSuperclasses()
+    {
+        factory.createInvokerProxy(new NullInvoker(), new Class[] { EchoImpl.class, String.class });
+    }
+
+    @Override
+    @Test
+    public void testInvokerEquals() throws Exception
+    {
+        final Date proxy1 = factory.createInvokerProxy(new InvokerTester(), DATE_ONLY);
+        final Date proxy2 = factory.createInvokerProxy(new InvokerTester(), DATE_ONLY);
+        assertEquals(proxy1, proxy1);
+        assertFalse(proxy1.equals(proxy2));
+        assertFalse(proxy2.equals(proxy1));
+    }
+
+    @Test
+    public void testInvokerWithSuperclass()
+    {
+        final Echo echo = factory.createInvokerProxy(new NullInvoker(), new Class[] { Echo.class, EchoImpl.class });
+        assertTrue(echo instanceof EchoImpl);
+    }
+
+    @Test
+    public void testProxiesWithClashingFinalMethodInSuperclass()
+    {
+        final Class<?>[] proxyClasses = new Class[] { Echo.class, FinalMethodEcho.class };
+        Echo proxy = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), proxyClasses);
+        assertEquals("final", proxy.echoBack("echo"));
+
+        proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), proxyClasses);
+        assertEquals("final", proxy.echoBack("echo"));
+
+        proxy = factory.createInvokerProxy(new NullInvoker(), proxyClasses);
+        assertEquals("final", proxy.echoBack("echo"));
+    }
+
+    @Test
+    public void testWithAbstractSuperclass()
+    {
+        final Echo echo = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()),
+                new Class[] { AbstractEcho.class });
+        assertEquals("hello", echo.echoBack("hello"));
+        assertEquals("helloworld", echo.echoBack("hello", "world"));
+    }
+
+    //----------------------------------------------------------------------------------------------------------------------
+    // Inner Classes
+    //----------------------------------------------------------------------------------------------------------------------
+
+    public static class EqualsEcho extends EchoImpl
+    {
+        @SuppressWarnings("unused")
+        private final String text;
+
+        protected EqualsEcho()
+        {
+            this("testing");
+        }
+
+        public EqualsEcho(String text)
+        {
+            this.text = text;
+        }
+    }
+
+    public static final class FinalEcho extends EchoImpl
+    {
+    }
+
+    public static class FinalMethodEcho extends EchoImpl
+    {
+        @Override
+        public final String echoBack(String message)
+        {
+            return "final";
+        }
+    }
+
+    private static class InvisibleEcho extends EchoImpl
+    {
+    }
+
+    public static class NoDefaultConstructorEcho extends EchoImpl
+    {
+        public NoDefaultConstructorEcho(String param)
+        {
+        }
+    }
+
+    public static class ProtectedConstructorEcho extends EchoImpl
+    {
+        protected ProtectedConstructorEcho()
+        {
+        }
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/AbstractEcho.java b/core/src/test/java/org/apache/commons/proxy2/util/AbstractEcho.java
index cb8e02f..04405f1 100644
--- a/core/src/test/java/org/apache/commons/proxy2/util/AbstractEcho.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/AbstractEcho.java
@@ -1,34 +1,34 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements.  See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache License, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License.  You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package org.apache.commons.proxy2.util;

-

-import java.io.Serializable;

-

-@SuppressWarnings("serial")

-public abstract class AbstractEcho implements Echo, Serializable

-{

-    //**********************************************************************************************************************

-    // Echo Implementation

-    //**********************************************************************************************************************

-

-    @Override

-    public String echoBack(String message)

-    {

-        return message;

-    }

-}

+/*
+ * 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.proxy2.util;
+
+import java.io.Serializable;
+
+@SuppressWarnings("serial")
+public abstract class AbstractEcho implements Echo, Serializable
+{
+    //**********************************************************************************************************************
+    // Echo Implementation
+    //**********************************************************************************************************************
+
+    @Override
+    public String echoBack(String message)
+    {
+        return message;
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/AbstractTestCase.java b/core/src/test/java/org/apache/commons/proxy2/util/AbstractTestCase.java
index 93b732d..9cb0cd9 100644
--- a/core/src/test/java/org/apache/commons/proxy2/util/AbstractTestCase.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/AbstractTestCase.java
@@ -1,83 +1,83 @@
-/*

- * 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.proxy2.util;

-

-import static org.junit.Assert.assertTrue;

-

-import java.io.Serializable;

-import java.lang.reflect.Method;

-

-import org.apache.commons.lang3.SerializationUtils;

-import org.apache.commons.lang3.Validate;

-import org.apache.commons.lang3.builder.Builder;

-import org.apache.commons.proxy2.Invocation;

-import org.apache.commons.proxy2.ProxyUtils;

-

-public abstract class AbstractTestCase

-{

-    //**********************************************************************************************************************

-    // Other Methods

-    //**********************************************************************************************************************

-

-    protected void assertSerializable(Object o)

-    {

-        assertTrue(o instanceof Serializable);

-        SerializationUtils.clone((Serializable) o);

-    }

-

-    protected MockInvocationBuilder mockInvocation(Class<?> type, String name, Class<?>... argumentTypes)

-    {

-        try

-        {

-            return new MockInvocationBuilder(Validate.notNull(type).getMethod(name, argumentTypes));

-        }

-        catch (NoSuchMethodException e)

-        {

-            throw new IllegalArgumentException("Method not found.", e);

-        }

-    }

-

-    protected static final class MockInvocationBuilder implements Builder<Invocation>

-    {

-        private final Method method;

-        private Object[] arguments = ProxyUtils.EMPTY_ARGUMENTS;

-        private Object returnValue = null;

-

-        public MockInvocationBuilder(Method method)

-        {

-            this.method = method;

-        }

-

-        public MockInvocationBuilder withArguments(Object... arguments)

-        {

-            this.arguments = arguments;

-            return this;

-        }

-

-        public MockInvocationBuilder returning(Object value)

-        {

-            this.returnValue = value;

-            return this;

-        }

-

-        @Override

-        public Invocation build()

-        {

-            return new MockInvocation(method, returnValue, arguments);

-        }

-    }

-}

+/*
+ * 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.proxy2.util;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.builder.Builder;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.ProxyUtils;
+
+public abstract class AbstractTestCase
+{
+    //**********************************************************************************************************************
+    // Other Methods
+    //**********************************************************************************************************************
+
+    protected void assertSerializable(Object o)
+    {
+        assertTrue(o instanceof Serializable);
+        SerializationUtils.clone((Serializable) o);
+    }
+
+    protected MockInvocationBuilder mockInvocation(Class<?> type, String name, Class<?>... argumentTypes)
+    {
+        try
+        {
+            return new MockInvocationBuilder(Validate.notNull(type).getMethod(name, argumentTypes));
+        }
+        catch (NoSuchMethodException e)
+        {
+            throw new IllegalArgumentException("Method not found.", e);
+        }
+    }
+
+    protected static final class MockInvocationBuilder implements Builder<Invocation>
+    {
+        private final Method method;
+        private Object[] arguments = ProxyUtils.EMPTY_ARGUMENTS;
+        private Object returnValue = null;
+
+        public MockInvocationBuilder(Method method)
+        {
+            this.method = method;
+        }
+
+        public MockInvocationBuilder withArguments(Object... arguments)
+        {
+            this.arguments = arguments;
+            return this;
+        }
+
+        public MockInvocationBuilder returning(Object value)
+        {
+            this.returnValue = value;
+            return this;
+        }
+
+        @Override
+        public Invocation build()
+        {
+            return new MockInvocation(method, returnValue, arguments);
+        }
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/DuplicateEcho.java b/core/src/test/java/org/apache/commons/proxy2/util/DuplicateEcho.java
index 07fd9fb..05b9d52 100644
--- a/core/src/test/java/org/apache/commons/proxy2/util/DuplicateEcho.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/DuplicateEcho.java
@@ -1,27 +1,27 @@
-/*

- * 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.proxy2.util;

-

-public interface DuplicateEcho

-{

-    //**********************************************************************************************************************

-    // Other Methods

-    //**********************************************************************************************************************

-

-    public String echoBack(String message);

-}

+/*
+ * 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.proxy2.util;
+
+public interface DuplicateEcho
+{
+    //**********************************************************************************************************************
+    // Other Methods
+    //**********************************************************************************************************************
+
+    public String echoBack(String message);
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/Echo.java b/core/src/test/java/org/apache/commons/proxy2/util/Echo.java
index 4e41b0b..66202e1 100644
--- a/core/src/test/java/org/apache/commons/proxy2/util/Echo.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/Echo.java
@@ -1,48 +1,48 @@
-/*

- * 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.proxy2.util;

-

-import java.io.IOException;

-

-public interface Echo

-{

-    //**********************************************************************************************************************

-    // Other Methods

-    //**********************************************************************************************************************

-

-    public void echo();

-

-    public String echoBack(String message);

-

-    public String echoBack(String[] messages);

-

-    public String echoBack(String[][] messages);

-

-    public String echoBack(String[][][] messages);

-

-    public int echoBack(int i);

-

-    public boolean echoBack(boolean b);

-

-    public String echoBack(String message1, String message2);

-

-    public void illegalArgument();

-

-    public void ioException() throws IOException;

-

-}

+/*
+ * 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.proxy2.util;
+
+import java.io.IOException;
+
+public interface Echo
+{
+    //**********************************************************************************************************************
+    // Other Methods
+    //**********************************************************************************************************************
+
+    public void echo();
+
+    public String echoBack(String message);
+
+    public String echoBack(String[] messages);
+
+    public String echoBack(String[][] messages);
+
+    public String echoBack(String[][][] messages);
+
+    public int echoBack(int i);
+
+    public boolean echoBack(boolean b);
+
+    public String echoBack(String message1, String message2);
+
+    public void illegalArgument();
+
+    public void ioException() throws IOException;
+
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/EchoImpl.java b/core/src/test/java/org/apache/commons/proxy2/util/EchoImpl.java
index d584b6f..919e134 100644
--- a/core/src/test/java/org/apache/commons/proxy2/util/EchoImpl.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/EchoImpl.java
@@ -1,103 +1,103 @@
-/*

- * 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.proxy2.util;

-

-import java.io.IOException;

-import java.io.Serializable;

-

-public class EchoImpl extends AbstractEcho implements DuplicateEcho, Serializable

-{

-    //**********************************************************************************************************************

-    // Fields

-    //**********************************************************************************************************************

-

-    private static final long serialVersionUID = -4844873352607521103L;

-

-    //**********************************************************************************************************************

-    // Echo Implementation

-    //**********************************************************************************************************************

-

-    @Override

-    public void echo()

-    {

-    }

-

-    @Override

-    public boolean echoBack(boolean b)

-    {

-        return b;

-    }

-

-    @Override

-    public String echoBack(String[] messages)

-    {

-        final StringBuilder sb = new StringBuilder();

-        for (int i = 0; i < messages.length; i++)

-        {

-            String message = messages[i];

-            sb.append(message);

-        }

-        return sb.toString();

-    }

-

-    @Override

-    public String echoBack(String[][] messages)

-    {

-        final StringBuilder sb = new StringBuilder();

-        for (int i = 0; i < messages.length; i++)

-        {

-            sb.append(echoBack(messages[i]));

-        }

-        return sb.toString();

-    }

-

-    @Override

-    public String echoBack(String[][][] messages)

-    {

-        final StringBuilder sb = new StringBuilder();

-        for (int i = 0; i < messages.length; i++)

-        {

-            sb.append(echoBack(messages[i]));

-        }

-        return sb.toString();

-    }

-

-    @Override

-    public int echoBack(int i)

-    {

-        return i;

-    }

-

-    @Override

-    public String echoBack(String message1, String message2)

-    {

-        return message1 + message2;

-    }

-

-    @Override

-    public void illegalArgument()

-    {

-        throw new IllegalArgumentException("dummy message");

-    }

-

-    @Override

-    public void ioException() throws IOException

-    {

-        throw new IOException("dummy message");

-    }

-}

+/*
+ * 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.proxy2.util;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+public class EchoImpl extends AbstractEcho implements DuplicateEcho, Serializable
+{
+    //**********************************************************************************************************************
+    // Fields
+    //**********************************************************************************************************************
+
+    private static final long serialVersionUID = -4844873352607521103L;
+
+    //**********************************************************************************************************************
+    // Echo Implementation
+    //**********************************************************************************************************************
+
+    @Override
+    public void echo()
+    {
+    }
+
+    @Override
+    public boolean echoBack(boolean b)
+    {
+        return b;
+    }
+
+    @Override
+    public String echoBack(String[] messages)
+    {
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < messages.length; i++)
+        {
+            String message = messages[i];
+            sb.append(message);
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String echoBack(String[][] messages)
+    {
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < messages.length; i++)
+        {
+            sb.append(echoBack(messages[i]));
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String echoBack(String[][][] messages)
+    {
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < messages.length; i++)
+        {
+            sb.append(echoBack(messages[i]));
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public int echoBack(int i)
+    {
+        return i;
+    }
+
+    @Override
+    public String echoBack(String message1, String message2)
+    {
+        return message1 + message2;
+    }
+
+    @Override
+    public void illegalArgument()
+    {
+        throw new IllegalArgumentException("dummy message");
+    }
+
+    @Override
+    public void ioException() throws IOException
+    {
+        throw new IOException("dummy message");
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/QuoteService.java b/core/src/test/java/org/apache/commons/proxy2/util/QuoteService.java
index 3728e3b..9bdffe6 100644
--- a/core/src/test/java/org/apache/commons/proxy2/util/QuoteService.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/QuoteService.java
@@ -1,30 +1,30 @@
-/*

- * 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.proxy2.util;

-

-import java.rmi.Remote;

-import java.rmi.RemoteException;

-

-public interface QuoteService extends Remote

-{

-    //**********************************************************************************************************************

-    // Other Methods

-    //**********************************************************************************************************************

-

-    public float getQuote(String symbol) throws RemoteException;

-}

+/*
+ * 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.proxy2.util;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+public interface QuoteService extends Remote
+{
+    //**********************************************************************************************************************
+    // Other Methods
+    //**********************************************************************************************************************
+
+    public float getQuote(String symbol) throws RemoteException;
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/SuffixInterceptor.java b/core/src/test/java/org/apache/commons/proxy2/util/SuffixInterceptor.java
index 89d8437..6bd3cc6 100644
--- a/core/src/test/java/org/apache/commons/proxy2/util/SuffixInterceptor.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/SuffixInterceptor.java
@@ -1,55 +1,55 @@
-/*

- * 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.proxy2.util;

-

-import org.apache.commons.proxy2.Interceptor;

-import org.apache.commons.proxy2.Invocation;

-

-@SuppressWarnings("serial")

-public class SuffixInterceptor implements Interceptor

-{

-    //**********************************************************************************************************************

-    // Fields

-    //**********************************************************************************************************************

-

-    private final String suffix;

-

-    //**********************************************************************************************************************

-    // Constructors

-    //**********************************************************************************************************************

-

-    public SuffixInterceptor(String suffix)

-    {

-        this.suffix = suffix;

-    }

-

-    //**********************************************************************************************************************

-    // Interceptor Implementation

-    //**********************************************************************************************************************

-

-    @Override

-    public Object intercept(Invocation methodInvocation) throws Throwable

-    {

-        Object result = methodInvocation.proceed();

-        if (result instanceof String)

-        {

-            result = ((String) result) + suffix;

-        }

-        return result;

-    }

-}

+/*
+ * 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.proxy2.util;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+
+@SuppressWarnings("serial")
+public class SuffixInterceptor implements Interceptor
+{
+    //**********************************************************************************************************************
+    // Fields
+    //**********************************************************************************************************************
+
+    private final String suffix;
+
+    //**********************************************************************************************************************
+    // Constructors
+    //**********************************************************************************************************************
+
+    public SuffixInterceptor(String suffix)
+    {
+        this.suffix = suffix;
+    }
+
+    //**********************************************************************************************************************
+    // Interceptor Implementation
+    //**********************************************************************************************************************
+
+    @Override
+    public Object intercept(Invocation methodInvocation) throws Throwable
+    {
+        Object result = methodInvocation.proceed();
+        if (result instanceof String)
+        {
+            result = ((String) result) + suffix;
+        }
+        return result;
+    }
+}
diff --git a/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistInvocation.java b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistInvocation.java
index b1961fe..b30ea50 100644
--- a/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistInvocation.java
+++ b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistInvocation.java
@@ -1,242 +1,242 @@
-/*

- * 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.proxy2.javassist;

-

-import java.lang.ref.WeakReference;

-import java.lang.reflect.Method;

-import java.util.HashMap;

-import java.util.Map;

-import java.util.WeakHashMap;

-

-import javassist.CannotCompileException;

-import javassist.CtClass;

-import javassist.CtConstructor;

-import javassist.CtMethod;

-

-import org.apache.commons.lang3.ArrayUtils;

-import org.apache.commons.lang3.ObjectUtils;

-import org.apache.commons.proxy2.Invocation;

-import org.apache.commons.proxy2.ProxyUtils;

-

-/**

- * A <a href="http://www.jboss.org/products/javassist">Javassist</a>-based {@link Invocation} implementation. This class

- * actually serves as the superclass for all <a href="http://www.jboss.org/products/javassist">Javassist</a>-based

- * method invocations. Subclasses are dynamically created to deal with specific interface methods (they're hard-wired).

- * 

- * @since 1.0

- */

-public abstract class JavassistInvocation implements Invocation

-{

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private static WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>> loaderToClassCache

-        = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();

-

-    /** The proxy object */

-    private final Object proxy;

-

-    /** The target object */

-    private final Object target;

-

-    /** The invoked method */

-    private final Method method;

-

-    /** The method arguments */

-    private final Object[] arguments;

-

-    //******************************************************************************************************************

-    // Static Methods

-    //******************************************************************************************************************

-

-    private static String createCastExpression(Class<?> type, String objectToCast)

-    {

-        if (!type.isPrimitive())

-        {

-            return "( " + ProxyUtils.getJavaClassName(type) + " )" + objectToCast;

-        }

-        else

-        {

-            return "( ( " + ProxyUtils.getWrapperClass(type).getName() + " )" + objectToCast + " )." + type.getName()

-                    + "Value()";

-        }

-    }

-

-    private static Class<?> createInvocationClass(ClassLoader classLoader, Method interfaceMethod)

-            throws CannotCompileException

-    {

-        final CtClass ctClass = JavassistUtils.createClass(getSimpleName(interfaceMethod.getDeclaringClass()) + "_"

-                + interfaceMethod.getName() + "_invocation", JavassistInvocation.class);

-        final CtConstructor constructor = new CtConstructor(JavassistUtils.resolve(new Class[] { Object.class,

-                Object.class, Method.class, Object[].class }), ctClass);

-        constructor.setBody("{\n\tsuper($$);\n}");

-        ctClass.addConstructor(constructor);

-        final CtMethod proceedMethod = new CtMethod(JavassistUtils.resolve(Object.class), "proceed",

-                JavassistUtils.resolve(new Class[0]), ctClass);

-        final Class<?>[] argumentTypes = interfaceMethod.getParameterTypes();

-        final StringBuilder proceedBody = new StringBuilder("{\n");

-        if (!Void.TYPE.equals(interfaceMethod.getReturnType()))

-        {

-            proceedBody.append("\treturn ");

-            if (interfaceMethod.getReturnType().isPrimitive())

-            {

-                proceedBody.append("new ");

-                proceedBody.append(ProxyUtils.getWrapperClass(interfaceMethod.getReturnType()).getName());

-                proceedBody.append("( ");

-            }

-        }

-        else

-        {

-            proceedBody.append("\t");

-        }

-        proceedBody.append("( (");

-        proceedBody.append(ProxyUtils.getJavaClassName(interfaceMethod.getDeclaringClass()));

-        proceedBody.append(" )getTarget() ).");

-        proceedBody.append(interfaceMethod.getName());

-        proceedBody.append("(");

-        for (int i = 0; i < argumentTypes.length; ++i)

-        {

-            final Class<?> argumentType = argumentTypes[i];

-            proceedBody.append(createCastExpression(argumentType, "getArguments()[" + i + "]"));

-            if (i != argumentTypes.length - 1)

-            {

-                proceedBody.append(", ");

-            }

-        }

-        if (!Void.TYPE.equals(interfaceMethod.getReturnType()) && interfaceMethod.getReturnType().isPrimitive())

-        {

-            proceedBody.append(") );\n");

-        }

-        else

-        {

-            proceedBody.append(");\n");

-        }

-        if (Void.TYPE.equals(interfaceMethod.getReturnType()))

-        {

-            proceedBody.append("\treturn null;\n");

-        }

-        proceedBody.append("}");

-        final String body = proceedBody.toString();

-        proceedMethod.setBody(body);

-        ctClass.addMethod(proceedMethod);

-

-        @SuppressWarnings("deprecation")

-        final Class<?> invocationClass = ctClass.toClass(classLoader);

-        return invocationClass;

-    }

-

-    private static Map<String, WeakReference<Class<?>>> getClassCache(ClassLoader classLoader)

-    {

-        Map<String, WeakReference<Class<?>>> cache = loaderToClassCache.get(classLoader);

-        if (cache == null)

-        {

-            cache = new HashMap<String, WeakReference<Class<?>>>();

-            loaderToClassCache.put(classLoader, cache);

-        }

-        return cache;

-    }

-

-    /**

-     * Returns a method invocation class specifically coded to invoke the supplied interface method.

-     * 

-     * @param classLoader

-     *            the classloader to use

-     * @param interfaceMethod

-     *            the interface method

-     * @return a method invocation class specifically coded to invoke the supplied interface method

-     * @throws CannotCompileException

-     *             if a compilation error occurs

-     */

-    static synchronized Class<?> getMethodInvocationClass(ClassLoader classLoader, Method interfaceMethod)

-            throws CannotCompileException

-    {

-        final Map<String, WeakReference<Class<?>>> classCache = getClassCache(classLoader);

-        final String key = toClassCacheKey(interfaceMethod);

-        final WeakReference<Class<?>> invocationClassRef = classCache.get(key);

-        Class<?> invocationClass;

-        if (invocationClassRef == null)

-        {

-            invocationClass = createInvocationClass(classLoader, interfaceMethod);

-            classCache.put(key, new WeakReference<Class<?>>(invocationClass));

-        }

-        else

-        {

-            synchronized (invocationClassRef)

-            {

-                invocationClass = invocationClassRef.get();

-                if (invocationClass == null)

-                {

-                    invocationClass = createInvocationClass(classLoader, interfaceMethod);

-                    classCache.put(key, new WeakReference<Class<?>>(invocationClass));

-                }

-            }

-        }

-        return invocationClass;

-    }

-

-    private static String getSimpleName(Class<?> c)

-    {

-        final String name = c.getName();

-        final int ndx = name.lastIndexOf('.');

-        return ndx == -1 ? name : name.substring(ndx + 1);

-    }

-

-    private static String toClassCacheKey(Method method)

-    {

-        return String.valueOf(method);

-    }

-

-    //******************************************************************************************************************

-    // Constructors

-    //******************************************************************************************************************

-

-    protected JavassistInvocation(Object proxy, Object target, Method method, Object[] arguments)

-    {

-        this.proxy = proxy;

-        this.target = target;

-        this.method = method;

-        this.arguments = ObjectUtils.defaultIfNull(ArrayUtils.clone(arguments), ProxyUtils.EMPTY_ARGUMENTS);

-    }

-

-    //******************************************************************************************************************

-    // Invocation Implementation

-    //******************************************************************************************************************

-    protected final Object getTarget()

-    {

-        return target;

-    }

-

-    @Override

-    public Object[] getArguments()

-    {

-        return arguments;

-    }

-

-    @Override

-    public Method getMethod()

-    {

-        return method;

-    }

-

-    @Override

-    public Object getProxy()

-    {

-        return proxy;

-    }

-}

+/*
+ * 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.proxy2.javassist;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javassist.CannotCompileException;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.ProxyUtils;
+
+/**
+ * A <a href="http://www.jboss.org/products/javassist">Javassist</a>-based {@link Invocation} implementation. This class
+ * actually serves as the superclass for all <a href="http://www.jboss.org/products/javassist">Javassist</a>-based
+ * method invocations. Subclasses are dynamically created to deal with specific interface methods (they're hard-wired).
+ * 
+ * @since 1.0
+ */
+public abstract class JavassistInvocation implements Invocation
+{
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private static WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>> loaderToClassCache
+        = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();
+
+    /** The proxy object */
+    private final Object proxy;
+
+    /** The target object */
+    private final Object target;
+
+    /** The invoked method */
+    private final Method method;
+
+    /** The method arguments */
+    private final Object[] arguments;
+
+    //******************************************************************************************************************
+    // Static Methods
+    //******************************************************************************************************************
+
+    private static String createCastExpression(Class<?> type, String objectToCast)
+    {
+        if (!type.isPrimitive())
+        {
+            return "( " + ProxyUtils.getJavaClassName(type) + " )" + objectToCast;
+        }
+        else
+        {
+            return "( ( " + ProxyUtils.getWrapperClass(type).getName() + " )" + objectToCast + " )." + type.getName()
+                    + "Value()";
+        }
+    }
+
+    private static Class<?> createInvocationClass(ClassLoader classLoader, Method interfaceMethod)
+            throws CannotCompileException
+    {
+        final CtClass ctClass = JavassistUtils.createClass(getSimpleName(interfaceMethod.getDeclaringClass()) + "_"
+                + interfaceMethod.getName() + "_invocation", JavassistInvocation.class);
+        final CtConstructor constructor = new CtConstructor(JavassistUtils.resolve(new Class[] { Object.class,
+                Object.class, Method.class, Object[].class }), ctClass);
+        constructor.setBody("{\n\tsuper($$);\n}");
+        ctClass.addConstructor(constructor);
+        final CtMethod proceedMethod = new CtMethod(JavassistUtils.resolve(Object.class), "proceed",
+                JavassistUtils.resolve(new Class[0]), ctClass);
+        final Class<?>[] argumentTypes = interfaceMethod.getParameterTypes();
+        final StringBuilder proceedBody = new StringBuilder("{\n");
+        if (!Void.TYPE.equals(interfaceMethod.getReturnType()))
+        {
+            proceedBody.append("\treturn ");
+            if (interfaceMethod.getReturnType().isPrimitive())
+            {
+                proceedBody.append("new ");
+                proceedBody.append(ProxyUtils.getWrapperClass(interfaceMethod.getReturnType()).getName());
+                proceedBody.append("( ");
+            }
+        }
+        else
+        {
+            proceedBody.append("\t");
+        }
+        proceedBody.append("( (");
+        proceedBody.append(ProxyUtils.getJavaClassName(interfaceMethod.getDeclaringClass()));
+        proceedBody.append(" )getTarget() ).");
+        proceedBody.append(interfaceMethod.getName());
+        proceedBody.append("(");
+        for (int i = 0; i < argumentTypes.length; ++i)
+        {
+            final Class<?> argumentType = argumentTypes[i];
+            proceedBody.append(createCastExpression(argumentType, "getArguments()[" + i + "]"));
+            if (i != argumentTypes.length - 1)
+            {
+                proceedBody.append(", ");
+            }
+        }
+        if (!Void.TYPE.equals(interfaceMethod.getReturnType()) && interfaceMethod.getReturnType().isPrimitive())
+        {
+            proceedBody.append(") );\n");
+        }
+        else
+        {
+            proceedBody.append(");\n");
+        }
+        if (Void.TYPE.equals(interfaceMethod.getReturnType()))
+        {
+            proceedBody.append("\treturn null;\n");
+        }
+        proceedBody.append("}");
+        final String body = proceedBody.toString();
+        proceedMethod.setBody(body);
+        ctClass.addMethod(proceedMethod);
+
+        @SuppressWarnings("deprecation")
+        final Class<?> invocationClass = ctClass.toClass(classLoader);
+        return invocationClass;
+    }
+
+    private static Map<String, WeakReference<Class<?>>> getClassCache(ClassLoader classLoader)
+    {
+        Map<String, WeakReference<Class<?>>> cache = loaderToClassCache.get(classLoader);
+        if (cache == null)
+        {
+            cache = new HashMap<String, WeakReference<Class<?>>>();
+            loaderToClassCache.put(classLoader, cache);
+        }
+        return cache;
+    }
+
+    /**
+     * Returns a method invocation class specifically coded to invoke the supplied interface method.
+     * 
+     * @param classLoader
+     *            the classloader to use
+     * @param interfaceMethod
+     *            the interface method
+     * @return a method invocation class specifically coded to invoke the supplied interface method
+     * @throws CannotCompileException
+     *             if a compilation error occurs
+     */
+    static synchronized Class<?> getMethodInvocationClass(ClassLoader classLoader, Method interfaceMethod)
+            throws CannotCompileException
+    {
+        final Map<String, WeakReference<Class<?>>> classCache = getClassCache(classLoader);
+        final String key = toClassCacheKey(interfaceMethod);
+        final WeakReference<Class<?>> invocationClassRef = classCache.get(key);
+        Class<?> invocationClass;
+        if (invocationClassRef == null)
+        {
+            invocationClass = createInvocationClass(classLoader, interfaceMethod);
+            classCache.put(key, new WeakReference<Class<?>>(invocationClass));
+        }
+        else
+        {
+            synchronized (invocationClassRef)
+            {
+                invocationClass = invocationClassRef.get();
+                if (invocationClass == null)
+                {
+                    invocationClass = createInvocationClass(classLoader, interfaceMethod);
+                    classCache.put(key, new WeakReference<Class<?>>(invocationClass));
+                }
+            }
+        }
+        return invocationClass;
+    }
+
+    private static String getSimpleName(Class<?> c)
+    {
+        final String name = c.getName();
+        final int ndx = name.lastIndexOf('.');
+        return ndx == -1 ? name : name.substring(ndx + 1);
+    }
+
+    private static String toClassCacheKey(Method method)
+    {
+        return String.valueOf(method);
+    }
+
+    //******************************************************************************************************************
+    // Constructors
+    //******************************************************************************************************************
+
+    protected JavassistInvocation(Object proxy, Object target, Method method, Object[] arguments)
+    {
+        this.proxy = proxy;
+        this.target = target;
+        this.method = method;
+        this.arguments = ObjectUtils.defaultIfNull(ArrayUtils.clone(arguments), ProxyUtils.EMPTY_ARGUMENTS);
+    }
+
+    //******************************************************************************************************************
+    // Invocation Implementation
+    //******************************************************************************************************************
+    protected final Object getTarget()
+    {
+        return target;
+    }
+
+    @Override
+    public Object[] getArguments()
+    {
+        return arguments;
+    }
+
+    @Override
+    public Method getMethod()
+    {
+        return method;
+    }
+
+    @Override
+    public Object getProxy()
+    {
+        return proxy;
+    }
+}
diff --git a/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistProxyFactory.java b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistProxyFactory.java
index 04dece2..e94cbec 100644
--- a/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistProxyFactory.java
+++ b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistProxyFactory.java
@@ -1,275 +1,275 @@
-/*

- * 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.proxy2.javassist;

-

-import java.lang.reflect.Method;

-

-import javassist.CannotCompileException;

-import javassist.CtClass;

-import javassist.CtConstructor;

-import javassist.CtMethod;

-

-import org.apache.commons.proxy2.Interceptor;

-import org.apache.commons.proxy2.Invoker;

-import org.apache.commons.proxy2.ObjectProvider;

-import org.apache.commons.proxy2.ProxyUtils;

-import org.apache.commons.proxy2.exception.ProxyFactoryException;

-import org.apache.commons.proxy2.impl.AbstractProxyClassGenerator;

-import org.apache.commons.proxy2.impl.AbstractSubclassingProxyFactory;

-import org.apache.commons.proxy2.impl.ProxyClassCache;

-

-public class JavassistProxyFactory extends AbstractSubclassingProxyFactory

-{

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    private static final String GET_METHOD_METHOD_NAME = "_javassistGetMethod";

-

-    private static final ProxyClassCache DELEGATING_PROXY_CACHE = new ProxyClassCache(

-            new DelegatingProxyClassGenerator());

-    private static final ProxyClassCache INTERCEPTOR_PROXY_CACHE = new ProxyClassCache(

-            new InterceptorProxyClassGenerator());

-    private static final ProxyClassCache INVOKER_PROXY_CACHE = new ProxyClassCache(new InvokerProxyClassGenerator());

-

-    //******************************************************************************************************************

-    // Static Methods

-    //******************************************************************************************************************

-

-    private static void addGetMethodMethod(CtClass proxyClass) throws CannotCompileException

-    {

-        final CtMethod method = new CtMethod(JavassistUtils.resolve(Method.class), GET_METHOD_METHOD_NAME,

-                JavassistUtils.resolve(new Class[] { String.class, String.class, Class[].class }), proxyClass);

-        final String body = "try { return Class.forName($1).getMethod($2, $3); } catch( Exception e ) "

-                + "{ throw new RuntimeException(\"Unable to look up method.\", e); }";

-        method.setBody(body);

-        proxyClass.addMethod(method);

-    }

-

-    //******************************************************************************************************************

-    // ProxyFactory Implementation

-    //******************************************************************************************************************

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> targetProvider,

-            Class<?>... proxyClasses)

-    {

-        try

-        {

-            @SuppressWarnings("unchecked") // type inference

-            final Class<? extends T> clazz = (Class<? extends T>) DELEGATING_PROXY_CACHE.getProxyClass(classLoader,

-                    proxyClasses);

-            return clazz.getConstructor(ObjectProvider.class).newInstance(targetProvider);

-        }

-        catch (Exception e)

-        {

-            throw new ProxyFactoryException("Unable to instantiate proxy2 from generated proxy2 class.", e);

-        }

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,

-            Class<?>... proxyClasses)

-    {

-        try

-        {

-            @SuppressWarnings("unchecked") // type inference

-            final Class<? extends T> clazz = (Class<? extends T>) INTERCEPTOR_PROXY_CACHE.getProxyClass(classLoader,

-                    proxyClasses);

-            return clazz.getConstructor(Object.class, Interceptor.class).newInstance(target, interceptor);

-        }

-        catch (Exception e)

-        {

-            throw new ProxyFactoryException("Unable to instantiate proxy2 class instance.", e);

-        }

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    @Override

-    public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses)

-    {

-        try

-        {

-            @SuppressWarnings("unchecked") // type inference

-            final Class<? extends T> clazz = (Class<? extends T>) INVOKER_PROXY_CACHE.getProxyClass(classLoader,

-                    proxyClasses);

-            return clazz.getConstructor(Invoker.class).newInstance(invoker);

-        }

-        catch (Exception e)

-        {

-            throw new ProxyFactoryException("Unable to instantiate proxy2 from generated proxy2 class.", e);

-        }

-    }

-

-    //******************************************************************************************************************

-    // Inner Classes

-    //******************************************************************************************************************

-

-    private static class DelegatingProxyClassGenerator extends AbstractProxyClassGenerator

-    {

-        @Override

-        public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)

-        {

-            try

-            {

-                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));

-                JavassistUtils.addField(ObjectProvider.class, "provider", proxyClass);

-                final CtConstructor proxyConstructor = new CtConstructor(

-                        JavassistUtils.resolve(new Class[] { ObjectProvider.class }), proxyClass);

-                proxyConstructor.setBody("{ this.provider = $1; }");

-                proxyClass.addConstructor(proxyConstructor);

-                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));

-                addHashCodeMethod(proxyClass);

-                addEqualsMethod(proxyClass);

-                final Method[] methods = getImplementationMethods(proxyClasses);

-                for (int i = 0; i < methods.length; ++i)

-                {

-                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))

-                    {

-                        final Method method = methods[i];

-                        final CtMethod ctMethod = new CtMethod(JavassistUtils.resolve(method.getReturnType()),

-                                method.getName(), JavassistUtils.resolve(method.getParameterTypes()), proxyClass);

-                        final String body = "{ return ( $r ) ( ( " + method.getDeclaringClass().getName()

-                                + " )provider.getObject() )." + method.getName() + "($$); }";

-                        ctMethod.setBody(body);

-                        proxyClass.addMethod(ctMethod);

-                    }

-                }

-                return proxyClass.toClass(classLoader, null);

-            }

-            catch (CannotCompileException e)

-            {

-                throw new ProxyFactoryException("Could not compile class.", e);

-            }

-        }

-    }

-

-    private static class InterceptorProxyClassGenerator extends AbstractProxyClassGenerator

-    {

-        @Override

-        public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)

-        {

-            try

-            {

-                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));

-                final Method[] methods = getImplementationMethods(proxyClasses);

-                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));

-                JavassistUtils.addField(Object.class, "target", proxyClass);

-                JavassistUtils.addField(Interceptor.class, "interceptor", proxyClass);

-                addGetMethodMethod(proxyClass);

-                addHashCodeMethod(proxyClass);

-                addEqualsMethod(proxyClass);

-                final CtConstructor proxyConstructor = new CtConstructor(JavassistUtils.resolve(new Class[] {

-                        Object.class, Interceptor.class }), proxyClass);

-                proxyConstructor.setBody("{\n\tthis.target = $1;\n\tthis.interceptor = $2; }");

-                proxyClass.addConstructor(proxyConstructor);

-                for (int i = 0; i < methods.length; ++i)

-                {

-                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))

-                    {

-                        final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),

-                                methods[i].getName(), JavassistUtils.resolve(methods[i].getParameterTypes()),

-                                proxyClass);

-                        final Class<?> invocationClass = JavassistInvocation.getMethodInvocationClass(classLoader,

-                                methods[i]);

-

-                        final String body = "{\n\t return ( $r ) interceptor.intercept( new "

-                                + invocationClass.getName() + "( this, target, " + GET_METHOD_METHOD_NAME + "(\""

-                                + methods[i].getDeclaringClass().getName() + "\", \"" + methods[i].getName()

-                                + "\", $sig), $args ) );\n }";

-                        method.setBody(body);

-                        proxyClass.addMethod(method);

-                    }

-

-                }

-                return proxyClass.toClass(classLoader, null);

-            }

-            catch (CannotCompileException e)

-            {

-                throw new ProxyFactoryException("Could not compile class.", e);

-            }

-        }

-

-    }

-

-    private static void addEqualsMethod(CtClass proxyClass) throws CannotCompileException

-    {

-        final CtMethod equalsMethod = new CtMethod(JavassistUtils.resolve(Boolean.TYPE), "equals",

-                JavassistUtils.resolve(new Class[] { Object.class }), proxyClass);

-        final String body = "{\n\treturn this == $1;\n}";

-        equalsMethod.setBody(body);

-        proxyClass.addMethod(equalsMethod);

-    }

-

-    private static void addHashCodeMethod(CtClass proxyClass) throws CannotCompileException

-    {

-        final CtMethod hashCodeMethod = new CtMethod(JavassistUtils.resolve(Integer.TYPE), "hashCode", new CtClass[0],

-                proxyClass);

-        hashCodeMethod.setBody("{\n\treturn System.identityHashCode(this);\n}");

-        proxyClass.addMethod(hashCodeMethod);

-    }

-

-    private static class InvokerProxyClassGenerator extends AbstractProxyClassGenerator

-    {

-        @Override

-        public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)

-        {

-            try

-            {

-                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));

-                final Method[] methods = getImplementationMethods(proxyClasses);

-                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));

-                JavassistUtils.addField(Invoker.class, "invoker", proxyClass);

-                final CtConstructor proxyConstructor = new CtConstructor(

-                        JavassistUtils.resolve(new Class[] { Invoker.class }), proxyClass);

-                proxyConstructor.setBody("{\n\tthis.invoker = $1; }");

-                proxyClass.addConstructor(proxyConstructor);

-                addGetMethodMethod(proxyClass);

-                addHashCodeMethod(proxyClass);

-                addEqualsMethod(proxyClass);

-                for (int i = 0; i < methods.length; ++i)

-                {

-                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))

-                    {

-                        final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),

-                                methods[i].getName(), JavassistUtils.resolve(methods[i].getParameterTypes()),

-                                proxyClass);

-                        final String body = "{\n\t return ( $r ) invoker.invoke( this, " + GET_METHOD_METHOD_NAME

-                                + "(\"" + methods[i].getDeclaringClass().getName() + "\", \"" + methods[i].getName()

-                                + "\", $sig), $args );\n }";

-                        method.setBody(body);

-                        proxyClass.addMethod(method);

-                    }

-                }

-                return proxyClass.toClass(classLoader, null);

-            }

-            catch (CannotCompileException e)

-            {

-                throw new ProxyFactoryException("Could not compile class.", e);

-            }

-        }

-    }

-}

+/*
+ * 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.proxy2.javassist;
+
+import java.lang.reflect.Method;
+
+import javassist.CannotCompileException;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.exception.ProxyFactoryException;
+import org.apache.commons.proxy2.impl.AbstractProxyClassGenerator;
+import org.apache.commons.proxy2.impl.AbstractSubclassingProxyFactory;
+import org.apache.commons.proxy2.impl.ProxyClassCache;
+
+public class JavassistProxyFactory extends AbstractSubclassingProxyFactory
+{
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    private static final String GET_METHOD_METHOD_NAME = "_javassistGetMethod";
+
+    private static final ProxyClassCache DELEGATING_PROXY_CACHE = new ProxyClassCache(
+            new DelegatingProxyClassGenerator());
+    private static final ProxyClassCache INTERCEPTOR_PROXY_CACHE = new ProxyClassCache(
+            new InterceptorProxyClassGenerator());
+    private static final ProxyClassCache INVOKER_PROXY_CACHE = new ProxyClassCache(new InvokerProxyClassGenerator());
+
+    //******************************************************************************************************************
+    // Static Methods
+    //******************************************************************************************************************
+
+    private static void addGetMethodMethod(CtClass proxyClass) throws CannotCompileException
+    {
+        final CtMethod method = new CtMethod(JavassistUtils.resolve(Method.class), GET_METHOD_METHOD_NAME,
+                JavassistUtils.resolve(new Class[] { String.class, String.class, Class[].class }), proxyClass);
+        final String body = "try { return Class.forName($1).getMethod($2, $3); } catch( Exception e ) "
+                + "{ throw new RuntimeException(\"Unable to look up method.\", e); }";
+        method.setBody(body);
+        proxyClass.addMethod(method);
+    }
+
+    //******************************************************************************************************************
+    // ProxyFactory Implementation
+    //******************************************************************************************************************
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> targetProvider,
+            Class<?>... proxyClasses)
+    {
+        try
+        {
+            @SuppressWarnings("unchecked") // type inference
+            final Class<? extends T> clazz = (Class<? extends T>) DELEGATING_PROXY_CACHE.getProxyClass(classLoader,
+                    proxyClasses);
+            return clazz.getConstructor(ObjectProvider.class).newInstance(targetProvider);
+        }
+        catch (Exception e)
+        {
+            throw new ProxyFactoryException("Unable to instantiate proxy2 from generated proxy2 class.", e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
+            Class<?>... proxyClasses)
+    {
+        try
+        {
+            @SuppressWarnings("unchecked") // type inference
+            final Class<? extends T> clazz = (Class<? extends T>) INTERCEPTOR_PROXY_CACHE.getProxyClass(classLoader,
+                    proxyClasses);
+            return clazz.getConstructor(Object.class, Interceptor.class).newInstance(target, interceptor);
+        }
+        catch (Exception e)
+        {
+            throw new ProxyFactoryException("Unable to instantiate proxy2 class instance.", e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses)
+    {
+        try
+        {
+            @SuppressWarnings("unchecked") // type inference
+            final Class<? extends T> clazz = (Class<? extends T>) INVOKER_PROXY_CACHE.getProxyClass(classLoader,
+                    proxyClasses);
+            return clazz.getConstructor(Invoker.class).newInstance(invoker);
+        }
+        catch (Exception e)
+        {
+            throw new ProxyFactoryException("Unable to instantiate proxy2 from generated proxy2 class.", e);
+        }
+    }
+
+    //******************************************************************************************************************
+    // Inner Classes
+    //******************************************************************************************************************
+
+    private static class DelegatingProxyClassGenerator extends AbstractProxyClassGenerator
+    {
+        @Override
+        public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)
+        {
+            try
+            {
+                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
+                JavassistUtils.addField(ObjectProvider.class, "provider", proxyClass);
+                final CtConstructor proxyConstructor = new CtConstructor(
+                        JavassistUtils.resolve(new Class[] { ObjectProvider.class }), proxyClass);
+                proxyConstructor.setBody("{ this.provider = $1; }");
+                proxyClass.addConstructor(proxyConstructor);
+                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
+                addHashCodeMethod(proxyClass);
+                addEqualsMethod(proxyClass);
+                final Method[] methods = getImplementationMethods(proxyClasses);
+                for (int i = 0; i < methods.length; ++i)
+                {
+                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
+                    {
+                        final Method method = methods[i];
+                        final CtMethod ctMethod = new CtMethod(JavassistUtils.resolve(method.getReturnType()),
+                                method.getName(), JavassistUtils.resolve(method.getParameterTypes()), proxyClass);
+                        final String body = "{ return ( $r ) ( ( " + method.getDeclaringClass().getName()
+                                + " )provider.getObject() )." + method.getName() + "($$); }";
+                        ctMethod.setBody(body);
+                        proxyClass.addMethod(ctMethod);
+                    }
+                }
+                return proxyClass.toClass(classLoader, null);
+            }
+            catch (CannotCompileException e)
+            {
+                throw new ProxyFactoryException("Could not compile class.", e);
+            }
+        }
+    }
+
+    private static class InterceptorProxyClassGenerator extends AbstractProxyClassGenerator
+    {
+        @Override
+        public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)
+        {
+            try
+            {
+                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
+                final Method[] methods = getImplementationMethods(proxyClasses);
+                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
+                JavassistUtils.addField(Object.class, "target", proxyClass);
+                JavassistUtils.addField(Interceptor.class, "interceptor", proxyClass);
+                addGetMethodMethod(proxyClass);
+                addHashCodeMethod(proxyClass);
+                addEqualsMethod(proxyClass);
+                final CtConstructor proxyConstructor = new CtConstructor(JavassistUtils.resolve(new Class[] {
+                        Object.class, Interceptor.class }), proxyClass);
+                proxyConstructor.setBody("{\n\tthis.target = $1;\n\tthis.interceptor = $2; }");
+                proxyClass.addConstructor(proxyConstructor);
+                for (int i = 0; i < methods.length; ++i)
+                {
+                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
+                    {
+                        final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),
+                                methods[i].getName(), JavassistUtils.resolve(methods[i].getParameterTypes()),
+                                proxyClass);
+                        final Class<?> invocationClass = JavassistInvocation.getMethodInvocationClass(classLoader,
+                                methods[i]);
+
+                        final String body = "{\n\t return ( $r ) interceptor.intercept( new "
+                                + invocationClass.getName() + "( this, target, " + GET_METHOD_METHOD_NAME + "(\""
+                                + methods[i].getDeclaringClass().getName() + "\", \"" + methods[i].getName()
+                                + "\", $sig), $args ) );\n }";
+                        method.setBody(body);
+                        proxyClass.addMethod(method);
+                    }
+
+                }
+                return proxyClass.toClass(classLoader, null);
+            }
+            catch (CannotCompileException e)
+            {
+                throw new ProxyFactoryException("Could not compile class.", e);
+            }
+        }
+
+    }
+
+    private static void addEqualsMethod(CtClass proxyClass) throws CannotCompileException
+    {
+        final CtMethod equalsMethod = new CtMethod(JavassistUtils.resolve(Boolean.TYPE), "equals",
+                JavassistUtils.resolve(new Class[] { Object.class }), proxyClass);
+        final String body = "{\n\treturn this == $1;\n}";
+        equalsMethod.setBody(body);
+        proxyClass.addMethod(equalsMethod);
+    }
+
+    private static void addHashCodeMethod(CtClass proxyClass) throws CannotCompileException
+    {
+        final CtMethod hashCodeMethod = new CtMethod(JavassistUtils.resolve(Integer.TYPE), "hashCode", new CtClass[0],
+                proxyClass);
+        hashCodeMethod.setBody("{\n\treturn System.identityHashCode(this);\n}");
+        proxyClass.addMethod(hashCodeMethod);
+    }
+
+    private static class InvokerProxyClassGenerator extends AbstractProxyClassGenerator
+    {
+        @Override
+        public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)
+        {
+            try
+            {
+                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
+                final Method[] methods = getImplementationMethods(proxyClasses);
+                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
+                JavassistUtils.addField(Invoker.class, "invoker", proxyClass);
+                final CtConstructor proxyConstructor = new CtConstructor(
+                        JavassistUtils.resolve(new Class[] { Invoker.class }), proxyClass);
+                proxyConstructor.setBody("{\n\tthis.invoker = $1; }");
+                proxyClass.addConstructor(proxyConstructor);
+                addGetMethodMethod(proxyClass);
+                addHashCodeMethod(proxyClass);
+                addEqualsMethod(proxyClass);
+                for (int i = 0; i < methods.length; ++i)
+                {
+                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
+                    {
+                        final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),
+                                methods[i].getName(), JavassistUtils.resolve(methods[i].getParameterTypes()),
+                                proxyClass);
+                        final String body = "{\n\t return ( $r ) invoker.invoke( this, " + GET_METHOD_METHOD_NAME
+                                + "(\"" + methods[i].getDeclaringClass().getName() + "\", \"" + methods[i].getName()
+                                + "\", $sig), $args );\n }";
+                        method.setBody(body);
+                        proxyClass.addMethod(method);
+                    }
+                }
+                return proxyClass.toClass(classLoader, null);
+            }
+            catch (CannotCompileException e)
+            {
+                throw new ProxyFactoryException("Could not compile class.", e);
+            }
+        }
+    }
+}
diff --git a/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistUtils.java b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistUtils.java
index a0bd2b2..43be772 100644
--- a/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistUtils.java
+++ b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistUtils.java
@@ -1,170 +1,170 @@
-/*

- * 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.proxy2.javassist;

-

-import java.util.HashSet;

-import java.util.Set;

-import java.util.concurrent.atomic.AtomicInteger;

-

-import javassist.CannotCompileException;

-import javassist.ClassPool;

-import javassist.CtClass;

-import javassist.CtField;

-import javassist.LoaderClassPath;

-import javassist.NotFoundException;

-

-import org.apache.commons.proxy2.ProxyUtils;

-import org.apache.commons.proxy2.exception.ObjectProviderException;

-

-/**

- * Some utility methods for dealing with Javassist. This class is not part of the public API!

- * 

- * @since 1.0

- */

-final class JavassistUtils

-{

-    //******************************************************************************************************************

-    // Fields

-    //******************************************************************************************************************

-

-    public static final String DEFAULT_BASE_NAME = "JavassistUtilsGenerated";

-    private static final AtomicInteger CLASS_NUMBER = new AtomicInteger(0);

-    private static final ClassPool CLASS_POOL = new ClassPool();

-    private static final Set<ClassLoader> CLASS_LOADERS = new HashSet<ClassLoader>();

-

-    //******************************************************************************************************************

-    // Static Methods

-    //******************************************************************************************************************

-

-    static

-    {

-        CLASS_POOL.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader()));

-    }

-

-    /**

-     * Adds a field to a class.

-     * 

-     * @param fieldType

-     *            the field's type

-     * @param fieldName

-     *            the field name

-     * @param enclosingClass

-     *            the class receiving the new field

-     * @throws CannotCompileException

-     *             if a compilation problem occurs

-     */

-    public static void addField(Class<?> fieldType, String fieldName, CtClass enclosingClass)

-            throws CannotCompileException

-    {

-        enclosingClass.addField(new CtField(resolve(fieldType), fieldName, enclosingClass));

-    }

-

-    /**

-     * Adds interfaces to a {@link CtClass}

-     * 

-     * @param ctClass

-     *            the {@link CtClass}

-     * @param proxyClasses

-     *            the interfaces

-     */

-    public static void addInterfaces(CtClass ctClass, Class<?>[] proxyClasses)

-    {

-        for (int i = 0; i < proxyClasses.length; i++)

-        {

-            Class<?> proxyInterface = proxyClasses[i];

-            ctClass.addInterface(resolve(proxyInterface));

-        }

-    }

-

-    /**

-     * Creates a new {@link CtClass} derived from the Java {@link Class} using the default base name.

-     * 

-     * @param superclass

-     *            the superclass

-     * @return the new derived {@link CtClass}

-     */

-    public static CtClass createClass(Class<?> superclass)

-    {

-        return createClass(DEFAULT_BASE_NAME, superclass);

-    }

-

-    /**

-     * Creates a new {@link CtClass} derived from the Java {@link Class} using the supplied base name.

-     * 

-     * @param baseName

-     *            the base name

-     * @param superclass

-     *            the superclass

-     * @return the new derived {@link CtClass}

-     */

-    public static synchronized CtClass createClass(String baseName, Class<?> superclass)

-    {

-        return CLASS_POOL.makeClass(baseName + "_" + CLASS_NUMBER.incrementAndGet(), resolve(superclass));

-    }

-

-    /**

-     * Finds the {@link CtClass} corresponding to the Java {@link Class} passed in.

-     * 

-     * @param clazz

-     *            the Java {@link Class}

-     * @return the {@link CtClass}

-     */

-    public static CtClass resolve(Class<?> clazz)

-    {

-        synchronized (CLASS_LOADERS)

-        {

-            try

-            {

-                final ClassLoader loader = clazz.getClassLoader();

-                if (loader != null && !CLASS_LOADERS.contains(loader))

-                {

-                    CLASS_LOADERS.add(loader);

-                    CLASS_POOL.appendClassPath(new LoaderClassPath(loader));

-                }

-                return CLASS_POOL.get(ProxyUtils.getJavaClassName(clazz));

-            }

-            catch (NotFoundException e)

-            {

-                throw new ObjectProviderException("Unable to find class " + clazz.getName()

-                        + " in default Javassist class pool.", e);

-            }

-        }

-    }

-

-    /**

-     * Resolves an array of Java {@link Class}es to an array of their corresponding {@link CtClass}es.

-     * 

-     * @param classes

-     *            the Java {@link Class}es

-     * @return the corresponding {@link CtClass}es

-     */

-    public static CtClass[] resolve(Class<?>[] classes)

-    {

-        final CtClass[] ctClasses = new CtClass[classes.length];

-        for (int i = 0; i < ctClasses.length; ++i)

-        {

-            ctClasses[i] = resolve(classes[i]);

-        }

-        return ctClasses;

-    }

-

-    private JavassistUtils()

-    {

-        // Hiding constructor in utility class!

-    }

-}

+/*
+ * 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.proxy2.javassist;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.LoaderClassPath;
+import javassist.NotFoundException;
+
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.exception.ObjectProviderException;
+
+/**
+ * Some utility methods for dealing with Javassist. This class is not part of the public API!
+ * 
+ * @since 1.0
+ */
+final class JavassistUtils
+{
+    //******************************************************************************************************************
+    // Fields
+    //******************************************************************************************************************
+
+    public static final String DEFAULT_BASE_NAME = "JavassistUtilsGenerated";
+    private static final AtomicInteger CLASS_NUMBER = new AtomicInteger(0);
+    private static final ClassPool CLASS_POOL = new ClassPool();
+    private static final Set<ClassLoader> CLASS_LOADERS = new HashSet<ClassLoader>();
+
+    //******************************************************************************************************************
+    // Static Methods
+    //******************************************************************************************************************
+
+    static
+    {
+        CLASS_POOL.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader()));
+    }
+
+    /**
+     * Adds a field to a class.
+     * 
+     * @param fieldType
+     *            the field's type
+     * @param fieldName
+     *            the field name
+     * @param enclosingClass
+     *            the class receiving the new field
+     * @throws CannotCompileException
+     *             if a compilation problem occurs
+     */
+    public static void addField(Class<?> fieldType, String fieldName, CtClass enclosingClass)
+            throws CannotCompileException
+    {
+        enclosingClass.addField(new CtField(resolve(fieldType), fieldName, enclosingClass));
+    }
+
+    /**
+     * Adds interfaces to a {@link CtClass}
+     * 
+     * @param ctClass
+     *            the {@link CtClass}
+     * @param proxyClasses
+     *            the interfaces
+     */
+    public static void addInterfaces(CtClass ctClass, Class<?>[] proxyClasses)
+    {
+        for (int i = 0; i < proxyClasses.length; i++)
+        {
+            Class<?> proxyInterface = proxyClasses[i];
+            ctClass.addInterface(resolve(proxyInterface));
+        }
+    }
+
+    /**
+     * Creates a new {@link CtClass} derived from the Java {@link Class} using the default base name.
+     * 
+     * @param superclass
+     *            the superclass
+     * @return the new derived {@link CtClass}
+     */
+    public static CtClass createClass(Class<?> superclass)
+    {
+        return createClass(DEFAULT_BASE_NAME, superclass);
+    }
+
+    /**
+     * Creates a new {@link CtClass} derived from the Java {@link Class} using the supplied base name.
+     * 
+     * @param baseName
+     *            the base name
+     * @param superclass
+     *            the superclass
+     * @return the new derived {@link CtClass}
+     */
+    public static synchronized CtClass createClass(String baseName, Class<?> superclass)
+    {
+        return CLASS_POOL.makeClass(baseName + "_" + CLASS_NUMBER.incrementAndGet(), resolve(superclass));
+    }
+
+    /**
+     * Finds the {@link CtClass} corresponding to the Java {@link Class} passed in.
+     * 
+     * @param clazz
+     *            the Java {@link Class}
+     * @return the {@link CtClass}
+     */
+    public static CtClass resolve(Class<?> clazz)
+    {
+        synchronized (CLASS_LOADERS)
+        {
+            try
+            {
+                final ClassLoader loader = clazz.getClassLoader();
+                if (loader != null && !CLASS_LOADERS.contains(loader))
+                {
+                    CLASS_LOADERS.add(loader);
+                    CLASS_POOL.appendClassPath(new LoaderClassPath(loader));
+                }
+                return CLASS_POOL.get(ProxyUtils.getJavaClassName(clazz));
+            }
+            catch (NotFoundException e)
+            {
+                throw new ObjectProviderException("Unable to find class " + clazz.getName()
+                        + " in default Javassist class pool.", e);
+            }
+        }
+    }
+
+    /**
+     * Resolves an array of Java {@link Class}es to an array of their corresponding {@link CtClass}es.
+     * 
+     * @param classes
+     *            the Java {@link Class}es
+     * @return the corresponding {@link CtClass}es
+     */
+    public static CtClass[] resolve(Class<?>[] classes)
+    {
+        final CtClass[] ctClasses = new CtClass[classes.length];
+        for (int i = 0; i < ctClasses.length; ++i)
+        {
+            ctClasses[i] = resolve(classes[i]);
+        }
+        return ctClasses;
+    }
+
+    private JavassistUtils()
+    {
+        // Hiding constructor in utility class!
+    }
+}
diff --git a/javassist/src/test/java/org/apache/commons/proxy2/javassist/JavassistProxyFactoryTest.java b/javassist/src/test/java/org/apache/commons/proxy2/javassist/JavassistProxyFactoryTest.java
index 839af29..a3be86c 100644
--- a/javassist/src/test/java/org/apache/commons/proxy2/javassist/JavassistProxyFactoryTest.java
+++ b/javassist/src/test/java/org/apache/commons/proxy2/javassist/JavassistProxyFactoryTest.java
@@ -1,26 +1,26 @@
-/*

- * 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.proxy2.javassist;

-

-import org.apache.commons.proxy2.AbstractSubclassingProxyFactoryTestCase;

-

-public class JavassistProxyFactoryTest extends AbstractSubclassingProxyFactoryTestCase

-{

-    //**********************************************************************************************************************

-    // Constructors

-    //**********************************************************************************************************************

-}

+/*
+ * 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.proxy2.javassist;
+
+import org.apache.commons.proxy2.AbstractSubclassingProxyFactoryTestCase;
+
+public class JavassistProxyFactoryTest extends AbstractSubclassingProxyFactoryTestCase
+{
+    //**********************************************************************************************************************
+    // Constructors
+    //**********************************************************************************************************************
+}
diff --git a/jdk/src/main/java/org/apache/commons/proxy2/jdk/JdkProxyFactory.java b/jdk/src/main/java/org/apache/commons/proxy2/jdk/JdkProxyFactory.java
index d3e5691..4d84963 100644
--- a/jdk/src/main/java/org/apache/commons/proxy2/jdk/JdkProxyFactory.java
+++ b/jdk/src/main/java/org/apache/commons/proxy2/jdk/JdkProxyFactory.java
@@ -1,251 +1,251 @@
-/*

- * 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.proxy2.jdk;

-

-import java.io.Serializable;

-import java.lang.reflect.InvocationHandler;

-import java.lang.reflect.InvocationTargetException;

-import java.lang.reflect.Method;

-import java.lang.reflect.Proxy;

-

-import org.apache.commons.lang3.ArrayUtils;

-import org.apache.commons.lang3.ObjectUtils;

-import org.apache.commons.proxy2.Interceptor;

-import org.apache.commons.proxy2.Invocation;

-import org.apache.commons.proxy2.Invoker;

-import org.apache.commons.proxy2.ObjectProvider;

-import org.apache.commons.proxy2.ProxyUtils;

-import org.apache.commons.proxy2.impl.AbstractProxyFactory;

-

-/**

- * {@link org.apache.commons.proxy2.ProxyFactory ProxyFactory} implementation that uses {@link java.lang.reflect.Proxy} proxies.

- */

-public class JdkProxyFactory extends AbstractProxyFactory

-{

-    //******************************************************************************************************************

-    // ProxyFactory Implementation

-    //******************************************************************************************************************

-

-    /**

-     * Creates a proxy2 which delegates to the object provided by <code>delegateProvider</code>.

-     * 

-     * @param classLoader

-     *            the class loader to use when generating the proxy2

-     * @param delegateProvider

-     *            the delegate provider

-     * @param proxyClasses

-     *            the interfaces that the proxy2 should implement

-     * @return a proxy2 which delegates to the object provided by the target <code>delegateProvider>

-     */

-    @Override

-    public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> delegateProvider,

-            Class<?>... proxyClasses)

-    {

-        @SuppressWarnings("unchecked") // type inference

-        final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new DelegatorInvocationHandler(

-                delegateProvider));

-        return result;

-    }

-

-    /**

-     * Creates a proxy2 which passes through a {@link Interceptor interceptor} before eventually reaching the

-     * <code>target</code> object.

-     * 

-     * @param classLoader

-     *            the class loader to use when generating the proxy2

-     * @param target

-     *            the target object

-     * @param interceptor

-     *            the method interceptor

-     * @param proxyClasses

-     *            the interfaces that the proxy2 should implement.

-     * @return a proxy2 which passes through a {@link Interceptor interceptor} before eventually reaching the

-     *         <code>target</code> object.

-     */

-    @Override

-    public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,

-            Class<?>... proxyClasses)

-    {

-        @SuppressWarnings("unchecked") // type inference

-        final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InterceptorInvocationHandler(target,

-                interceptor));

-        return result;

-    }

-

-    /**

-     * Creates a proxy2 which uses the provided {@link Invoker} to handle all method invocations.

-     * 

-     * @param classLoader

-     *            the class loader to use when generating the proxy2

-     * @param invoker

-     *            the invoker

-     * @param proxyClasses

-     *            the interfaces that the proxy2 should implement

-     * @return a proxy2 which uses the provided {@link Invoker} to handle all method invocations

-     */

-    @Override

-    public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses)

-    {

-        @SuppressWarnings("unchecked") // type inference

-        final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InvokerInvocationHandler(invoker));

-        return result;

-    }

-

-    //******************************************************************************************************************

-    // Inner Classes

-    //******************************************************************************************************************

-

-    private abstract static class AbstractInvocationHandler implements InvocationHandler, Serializable

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        @Override

-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

-        {

-            if (ProxyUtils.isHashCode(method))

-            {

-                return Integer.valueOf(System.identityHashCode(proxy));

-            }

-            else if (ProxyUtils.isEqualsMethod(method))

-            {

-                return Boolean.valueOf(proxy == args[0]);

-            }

-            else

-            {

-                return invokeImpl(proxy, method, args);

-            }

-        }

-

-        protected abstract Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable;

-    }

-

-    private static class DelegatorInvocationHandler extends AbstractInvocationHandler

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        private final ObjectProvider<?> delegateProvider;

-

-        protected DelegatorInvocationHandler(ObjectProvider<?> delegateProvider)

-        {

-            this.delegateProvider = delegateProvider;

-        }

-

-        @Override

-        public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable

-        {

-            try

-            {

-                return method.invoke(delegateProvider.getObject(), args);

-            }

-            catch (InvocationTargetException e)

-            {

-                throw e.getTargetException();

-            }

-        }

-    }

-

-    private static class InterceptorInvocationHandler extends AbstractInvocationHandler

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        private final Object target;

-        private final Interceptor methodInterceptor;

-

-        public InterceptorInvocationHandler(Object target, Interceptor methodInterceptor)

-        {

-            this.target = target;

-            this.methodInterceptor = methodInterceptor;

-        }

-

-        @Override

-        public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable

-        {

-            final ReflectionInvocation invocation = new ReflectionInvocation(proxy, target, method, args);

-            return methodInterceptor.intercept(invocation);

-        }

-    }

-

-    private static class InvokerInvocationHandler extends AbstractInvocationHandler

-    {

-        /** Serialization version */

-        private static final long serialVersionUID = 1L;

-

-        private final Invoker invoker;

-

-        public InvokerInvocationHandler(Invoker invoker)

-        {

-            this.invoker = invoker;

-        }

-

-        @Override

-        public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable

-        {

-            return invoker.invoke(proxy, method, args);

-        }

-    }

-

-    private static class ReflectionInvocation implements Invocation

-    {

-        private final Object proxy;

-        private final Object target;

-        private final Method method;

-        private final Object[] arguments;

-

-        public ReflectionInvocation(Object proxy, Object target, Method method, Object[] arguments)

-        {

-            this.proxy = proxy;

-            this.target = target;

-            this.method = method;

-            this.arguments = ObjectUtils.defaultIfNull(ArrayUtils.clone(arguments), ProxyUtils.EMPTY_ARGUMENTS);

-        }

-

-        @Override

-        public Object[] getArguments()

-        {

-            return arguments;

-        }

-

-        @Override

-        public Method getMethod()

-        {

-            return method;

-        }

-

-        @Override

-        public Object getProxy()

-        {

-            return proxy;

-        }

-

-        @Override

-        public Object proceed() throws Throwable

-        {

-            try

-            {

-                return method.invoke(target, arguments);

-            }

-            catch (InvocationTargetException e)

-            {

-                throw e.getTargetException();

-            }

-        }

-    }

-}

+/*
+ * 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.proxy2.jdk;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.impl.AbstractProxyFactory;
+
+/**
+ * {@link org.apache.commons.proxy2.ProxyFactory ProxyFactory} implementation that uses {@link java.lang.reflect.Proxy} proxies.
+ */
+public class JdkProxyFactory extends AbstractProxyFactory
+{
+    //******************************************************************************************************************
+    // ProxyFactory Implementation
+    //******************************************************************************************************************
+
+    /**
+     * Creates a proxy2 which delegates to the object provided by <code>delegateProvider</code>.
+     * 
+     * @param classLoader
+     *            the class loader to use when generating the proxy2
+     * @param delegateProvider
+     *            the delegate provider
+     * @param proxyClasses
+     *            the interfaces that the proxy2 should implement
+     * @return a proxy2 which delegates to the object provided by the target <code>delegateProvider>
+     */
+    @Override
+    public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> delegateProvider,
+            Class<?>... proxyClasses)
+    {
+        @SuppressWarnings("unchecked") // type inference
+        final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new DelegatorInvocationHandler(
+                delegateProvider));
+        return result;
+    }
+
+    /**
+     * Creates a proxy2 which passes through a {@link Interceptor interceptor} before eventually reaching the
+     * <code>target</code> object.
+     * 
+     * @param classLoader
+     *            the class loader to use when generating the proxy2
+     * @param target
+     *            the target object
+     * @param interceptor
+     *            the method interceptor
+     * @param proxyClasses
+     *            the interfaces that the proxy2 should implement.
+     * @return a proxy2 which passes through a {@link Interceptor interceptor} before eventually reaching the
+     *         <code>target</code> object.
+     */
+    @Override
+    public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
+            Class<?>... proxyClasses)
+    {
+        @SuppressWarnings("unchecked") // type inference
+        final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InterceptorInvocationHandler(target,
+                interceptor));
+        return result;
+    }
+
+    /**
+     * Creates a proxy2 which uses the provided {@link Invoker} to handle all method invocations.
+     * 
+     * @param classLoader
+     *            the class loader to use when generating the proxy2
+     * @param invoker
+     *            the invoker
+     * @param proxyClasses
+     *            the interfaces that the proxy2 should implement
+     * @return a proxy2 which uses the provided {@link Invoker} to handle all method invocations
+     */
+    @Override
+    public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses)
+    {
+        @SuppressWarnings("unchecked") // type inference
+        final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InvokerInvocationHandler(invoker));
+        return result;
+    }
+
+    //******************************************************************************************************************
+    // Inner Classes
+    //******************************************************************************************************************
+
+    private abstract static class AbstractInvocationHandler implements InvocationHandler, Serializable
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+        {
+            if (ProxyUtils.isHashCode(method))
+            {
+                return Integer.valueOf(System.identityHashCode(proxy));
+            }
+            else if (ProxyUtils.isEqualsMethod(method))
+            {
+                return Boolean.valueOf(proxy == args[0]);
+            }
+            else
+            {
+                return invokeImpl(proxy, method, args);
+            }
+        }
+
+        protected abstract Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable;
+    }
+
+    private static class DelegatorInvocationHandler extends AbstractInvocationHandler
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        private final ObjectProvider<?> delegateProvider;
+
+        protected DelegatorInvocationHandler(ObjectProvider<?> delegateProvider)
+        {
+            this.delegateProvider = delegateProvider;
+        }
+
+        @Override
+        public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
+        {
+            try
+            {
+                return method.invoke(delegateProvider.getObject(), args);
+            }
+            catch (InvocationTargetException e)
+            {
+                throw e.getTargetException();
+            }
+        }
+    }
+
+    private static class InterceptorInvocationHandler extends AbstractInvocationHandler
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        private final Object target;
+        private final Interceptor methodInterceptor;
+
+        public InterceptorInvocationHandler(Object target, Interceptor methodInterceptor)
+        {
+            this.target = target;
+            this.methodInterceptor = methodInterceptor;
+        }
+
+        @Override
+        public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
+        {
+            final ReflectionInvocation invocation = new ReflectionInvocation(proxy, target, method, args);
+            return methodInterceptor.intercept(invocation);
+        }
+    }
+
+    private static class InvokerInvocationHandler extends AbstractInvocationHandler
+    {
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        private final Invoker invoker;
+
+        public InvokerInvocationHandler(Invoker invoker)
+        {
+            this.invoker = invoker;
+        }
+
+        @Override
+        public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
+        {
+            return invoker.invoke(proxy, method, args);
+        }
+    }
+
+    private static class ReflectionInvocation implements Invocation
+    {
+        private final Object proxy;
+        private final Object target;
+        private final Method method;
+        private final Object[] arguments;
+
+        public ReflectionInvocation(Object proxy, Object target, Method method, Object[] arguments)
+        {
+            this.proxy = proxy;
+            this.target = target;
+            this.method = method;
+            this.arguments = ObjectUtils.defaultIfNull(ArrayUtils.clone(arguments), ProxyUtils.EMPTY_ARGUMENTS);
+        }
+
+        @Override
+        public Object[] getArguments()
+        {
+            return arguments;
+        }
+
+        @Override
+        public Method getMethod()
+        {
+            return method;
+        }
+
+        @Override
+        public Object getProxy()
+        {
+            return proxy;
+        }
+
+        @Override
+        public Object proceed() throws Throwable
+        {
+            try
+            {
+                return method.invoke(target, arguments);
+            }
+            catch (InvocationTargetException e)
+            {
+                throw e.getTargetException();
+            }
+        }
+    }
+}
diff --git a/jdk/src/test/java/org/apache/commons/proxy2/jdk/JdkProxyFactoryTest.java b/jdk/src/test/java/org/apache/commons/proxy2/jdk/JdkProxyFactoryTest.java
index 584001d..889051f 100644
--- a/jdk/src/test/java/org/apache/commons/proxy2/jdk/JdkProxyFactoryTest.java
+++ b/jdk/src/test/java/org/apache/commons/proxy2/jdk/JdkProxyFactoryTest.java
@@ -1,23 +1,23 @@
-/*

- * 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.proxy2.jdk;

-

-import org.apache.commons.proxy2.AbstractProxyFactoryTestCase;

-

-public class JdkProxyFactoryTest extends AbstractProxyFactoryTestCase

-{

-}

+/*
+ * 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.proxy2.jdk;
+
+import org.apache.commons.proxy2.AbstractProxyFactoryTestCase;
+
+public class JdkProxyFactoryTest extends AbstractProxyFactoryTestCase
+{
+}