com.google.guava
diff --git a/src/main/java/info/ludwikowski/fluentbuilder/common/AbstractBuilderFactory.java b/src/main/java/info/ludwikowski/fluentbuilder/common/AbstractBuilderFactory.java
index 6a5a6f9..b2db9f4 100644
--- a/src/main/java/info/ludwikowski/fluentbuilder/common/AbstractBuilderFactory.java
+++ b/src/main/java/info/ludwikowski/fluentbuilder/common/AbstractBuilderFactory.java
@@ -13,7 +13,6 @@
import net.sf.cglib.proxy.Enhancer;
-import org.springframework.core.GenericTypeResolver;
/**
* This class offers static methods for creating bean objects from builder
diff --git a/src/main/java/info/ludwikowski/fluentbuilder/common/GenericTypeResolver.java b/src/main/java/info/ludwikowski/fluentbuilder/common/GenericTypeResolver.java
new file mode 100644
index 0000000..7b73b97
--- /dev/null
+++ b/src/main/java/info/ludwikowski/fluentbuilder/common/GenericTypeResolver.java
@@ -0,0 +1,301 @@
+package info.ludwikowski.fluentbuilder.common;
+
+/*
+ * Copyright 2002-2011 the original author or authors.
+ *
+ * Licensed 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.
+ */
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+
+/**
+ * Helper class for resolving generic types against type variables.
+ *
+ *
+ * Mainly intended for usage within the framework, resolving method parameter types even when they are declared
+ * generically.
+ *
+ * @author Juergen Hoeller
+ * @author Rob Harrop
+ * @since 2.5.2
+ * @see GenericCollectionTypeResolver
+ */
+@SuppressWarnings("rawtypes")
+public abstract class GenericTypeResolver {
+
+ /** Cache from Class to TypeVariable Map */
+ private static final Map>> typeVariableCache =
+ Collections.synchronizedMap(new WeakHashMap>>());
+
+
+ /**
+ * Resolve the type arguments of the given generic interface against the given
+ * target class which is assumed to implement the generic interface and possibly
+ * declare concrete types for its type variables.
+ *
+ * @param clazz the target class to check against
+ * @param genericIfc the generic interface or superclass to resolve the type argument from
+ * @return the resolved type of each argument, with the array size matching the
+ * number of actual type arguments, or null
if not resolvable
+ */
+ public static Class[] resolveTypeArguments(Class clazz, Class genericIfc) {
+ return doResolveTypeArguments(clazz, clazz, genericIfc);
+ }
+
+ private static Class[] doResolveTypeArguments(Class ownerClass, Class classToIntrospect, Class genericIfc) {
+ while (classToIntrospect != null) {
+ if (genericIfc.isInterface()) {
+ Type[] ifcs = classToIntrospect.getGenericInterfaces();
+ for (Type ifc : ifcs) {
+ Class[] result = doResolveTypeArguments(ownerClass, ifc, genericIfc);
+ if (result != null) {
+ return result;
+ }
+ }
+ }
+ else {
+ Class[] result = doResolveTypeArguments(
+ ownerClass, classToIntrospect.getGenericSuperclass(), genericIfc);
+ if (result != null) {
+ return result;
+ }
+ }
+ classToIntrospect = classToIntrospect.getSuperclass();
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Class[] doResolveTypeArguments(Class ownerClass, Type ifc, Class genericIfc) {
+ if (ifc instanceof ParameterizedType) {
+ ParameterizedType paramIfc = (ParameterizedType) ifc;
+ Type rawType = paramIfc.getRawType();
+ if (genericIfc.equals(rawType)) {
+ Type[] typeArgs = paramIfc.getActualTypeArguments();
+ Class[] result = new Class[typeArgs.length];
+ for (int i = 0; i < typeArgs.length; i++) {
+ Type arg = typeArgs[i];
+ result[i] = extractClass(ownerClass, arg);
+ }
+ return result;
+ }
+ else if (genericIfc.isAssignableFrom((Class) rawType)) {
+ return doResolveTypeArguments(ownerClass, (Class) rawType, genericIfc);
+ }
+ }
+ else if (ifc != null && genericIfc.isAssignableFrom((Class) ifc)) {
+ return doResolveTypeArguments(ownerClass, (Class) ifc, genericIfc);
+ }
+ return null;
+ }
+
+ /**
+ * Extract a class instance from given Type.
+ */
+ private static Class extractClass(Class ownerClass, Type arg) {
+ if (arg instanceof ParameterizedType) {
+ return extractClass(ownerClass, ((ParameterizedType) arg).getRawType());
+ }
+ else if (arg instanceof GenericArrayType) {
+ GenericArrayType gat = (GenericArrayType) arg;
+ Type gt = gat.getGenericComponentType();
+ Class> componentClass = extractClass(ownerClass, gt);
+ return Array.newInstance(componentClass, 0).getClass();
+ }
+ else if (arg instanceof TypeVariable) {
+ TypeVariable tv = (TypeVariable) arg;
+ arg = getTypeVariableMap(ownerClass).get(tv);
+ if (arg == null) {
+ arg = extractBoundForTypeVariable(tv);
+ }
+ else {
+ arg = extractClass(ownerClass, arg);
+ }
+ }
+ return (arg instanceof Class ? (Class) arg : Object.class);
+ }
+
+ /**
+ * Resolve the specified generic type against the given TypeVariable map.
+ *
+ * @param genericType the generic type to resolve
+ * @param typeVariableMap the TypeVariable Map to resolved against
+ * @return the type if it resolves to a Class, or Object.class
otherwise
+ */
+ public static Class> resolveType(Type genericType, Map typeVariableMap) {
+ Type rawType = getRawType(genericType, typeVariableMap);
+ return (rawType instanceof Class ? (Class) rawType : Object.class);
+ }
+
+ /**
+ * Determine the raw type for the given generic parameter type.
+ *
+ * @param genericType the generic type to resolve
+ * @param typeVariableMap the TypeVariable Map to resolved against
+ * @return the resolved raw type
+ */
+ static Type getRawType(Type genericType, Map typeVariableMap) {
+ Type resolvedType = genericType;
+ if (genericType instanceof TypeVariable) {
+ TypeVariable tv = (TypeVariable) genericType;
+ resolvedType = typeVariableMap.get(tv);
+ if (resolvedType == null) {
+ resolvedType = extractBoundForTypeVariable(tv);
+ }
+ }
+ if (resolvedType instanceof ParameterizedType) {
+ return ((ParameterizedType) resolvedType).getRawType();
+ }
+ else {
+ return resolvedType;
+ }
+ }
+
+ /**
+ * Build a mapping of {@link TypeVariable#getName TypeVariable names} to concrete {@link Class} for the specified
+ * {@link Class}. Searches all super types,
+ * enclosing types and interfaces.
+ */
+ public static Map getTypeVariableMap(Class clazz) {
+ Reference