private static boolean typesHaveTheSameParameter(final Type thisArgument, final Type thatArgument, final TypeMap typeMap) {
        if (thisArgument.equals(thatArgument)) {
            return true;
        }

        if (isWildcard(thisArgument)) {
            if (isWildcard(thatArgument)) {
                return wildcardsAreAssignable((WildcardType) thisArgument, (WildcardType) thatArgument, typeMap);
            }

            else {
                return isAssignableFromWildcard((WildcardType) thisArgument, thatArgument, typeMap);
            }
        }

        else if (isTypeVariable(thatArgument)) {
            final TypeVariable<?> thatTypeVariable = (TypeVariable<?>) thatArgument;
            final Type thatResolvedType = typeMap.getActualType(thatTypeVariable);

            return typesHaveTheSameParameter(thisArgument, thatResolvedType, typeMap);
        }

        // This only happens with Java 7.
        // In Java 6 you will always get two GenericArrayTypes, and the match will happen on an earlier equals.
        else if (isClass(thisArgument) && isGenericArrayType(thatArgument)) {
            final Class<?> arrayClassFromGenericArray = getArrayClassFromGenericArray((GenericArrayType) thatArgument);
            return thisArgument.equals(arrayClassFromGenericArray);
        }

        return false;
    }