test_class.declarator: softly = new JUnitSoftAssertions()
test_class.modifier: @Rule
  	public
test_class.original_string: @Rule
  	public JUnitSoftAssertions softly = new JUnitSoftAssertions();
test_class.type: JUnitSoftAssertions
test_class.var_name: softly
test_class.file: restx-common/src/test/java/restx/common/TypesTest.java
test_class.identifier: TypesTest
test_case.body: @Test
  	public void isAssignableFrom_should_return_true_for_a_reifiable_type_and_any_sub_parameterized_type() {
  		softly.assertThat(isAssignableFrom(
  				List.class,
  				new TypeReference<ArrayList<String>>() {}.getType()
  		)).isTrue();
  
  		softly.assertThat(isAssignableFrom(
  				List.class,
  				new TypeReference<AbstractList<Integer>>() {}.getType()
  		)).isTrue();
  
  		softly.assertThat(isAssignableFrom(
  				Map.class,
  				new TypeReference<ImmutableList<String>>() {}.getType()
  		)).isFalse();
  
  		softly.assertThat(isAssignableFrom(
  				Map.class,
  				new TypeReference<ImmutableMap<String, Integer>>() {}.getType()
  		)).isTrue();
  	}
test_case.class_method_signature: TypesTest.isAssignableFrom_should_return_true_for_a_reifiable_type_and_any_sub_parameterized_type()
test_case.full_signature: @Test public void isAssignableFrom_should_return_true_for_a_reifiable_type_and_any_sub_parameterized_type()
test_case.identifier: isAssignableFrom_should_return_true_for_a_reifiable_type_and_any_sub_parameterized_type
test_case.invocations: isTrue assertThat isAssignableFrom getType isTrue assertThat isAssignableFrom getType isFalse assertThat isAssignableFrom getType isTrue assertThat isAssignableFrom getType
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void isAssignableFrom_should_return_true_for_a_reifiable_type_and_any_sub_parameterized_type()
focal_class.file: restx-common/src/main/java/restx/common/Types.java
focal_class.identifier: Types
focal_class.class_method_signature: Types.newParameterizedType(final Class<?> rawType, final Type... arguments)
focal_class.full_signature: public static ParameterizedType newParameterizedType(final Class<?> rawType, final Type... arguments)
focal_class.identifier: newParameterizedType
focal_class.modifiers: public static
focal_class.parameters: (final Class<?> rawType, final Type... arguments)
focal_class.return: ParameterizedType
focal_class.signature: ParameterizedType newParameterizedType(final Class<?> rawType, final Type... arguments)
focal_class.class_method_signature: Types.getRawType(Type type)
focal_class.full_signature: public static Class<?> getRawType(Type type)
focal_class.identifier: getRawType
focal_class.modifiers: public static
focal_class.parameters: (Type type)
focal_class.return: Class<?>
focal_class.signature: Class<?> getRawType(Type type)
focal_class.class_method_signature: Types.isAssignableFrom(Type t1, Type t2)
focal_class.full_signature: public static boolean isAssignableFrom(Type t1, Type t2)
focal_class.identifier: isAssignableFrom
focal_class.modifiers: public static
focal_class.parameters: (Type t1, Type t2)
focal_class.return: boolean
focal_class.signature: boolean isAssignableFrom(Type t1, Type t2)
focal_method.body: public static boolean isAssignableFrom(Type t1, Type t2) {
  		checkNotNull(t1);
  		checkNotNull(t2);
  
  		if (t1.equals(t2)) {
  			// easy case, types are equals
  			return true;
  		}
  
  		if (t1 instanceof Class<?>) {
  			/*
  				first type is a reifiable class, so any raw type, generic or not,
  				which is assignable by the raw type of t1 means that t1 is assignable from t2
  				and the reverse is also true
  			 */
  			return ((Class<?>) t1).isAssignableFrom(getRawType(t2));
  		}
  
  		if (t1 instanceof ParameterizedType) {
  			Class<?> rawTypeT1 = getRawType(t1);
  			Class<?> rawTypeT2 = getRawType(t2);
  
  			if (!rawTypeT1.isAssignableFrom(rawTypeT2) || rawTypeT1.equals(rawTypeT2)) {
  				/*
  					don't need to go further and to check generics, raw type of first type is not assignable
  					from second one, or raw types are equals but type aren't, so has one can not reference
  					a same type having a different generic type than his, it also means that t1 is not
  					assignable from t2
  				 */
  				return false;
  			}
  
  			if (t2 instanceof Class<?>) {
  				/*
  					we need to launch a recursive analysis on generic super type, and generic interfaces, because
  					t2 is a reifiable class, so there is no way that t1 can be directly assigned from t2,
  					so it has to be one of the sub-types of t2
  				 */
  
  				Type genericSuperclass = ((Class) t2).getGenericSuperclass();
  				if (genericSuperclass != null) {
  					if (isAssignableFrom(t1, genericSuperclass)) {
  						return true;
  					}
  				}
  				Type[] genericInterfaces = ((Class) t2).getGenericInterfaces();
  				for (Type genericInterface : genericInterfaces) {
  					if (isAssignableFrom(t1, genericInterface)) {
  						return true;
  					}
  				}
  
  				return false;
  			}
  
  			if (t2 instanceof ParameterizedType) {
  				/*
  					Extract generics type, and variables of the class, in order to know the concrete type of each variables
  				 */
  				Type[] actualTypeArguments = ((ParameterizedType) t2).getActualTypeArguments();
  				TypeVariable<? extends Class<?>>[] typeParameters = rawTypeT2.getTypeParameters();
  				Map<TypeVariable<? extends Class<?>>, Type> typesMap = Maps.newHashMapWithExpectedSize(typeParameters.length);
  				for (int i = 0; i < typeParameters.length; i++) {
  					typesMap.put(typeParameters[i], actualTypeArguments[i]);
  				}
  
  				/*
  					Try with the superclass, and fill variable with concrete types
  				 */
  				Type genericSuperclass = rawTypeT2.getGenericSuperclass();
  				if (genericSuperclass != null) {
  					if (genericSuperclass instanceof Class<?>) {
  						if (isAssignableFrom(t1, genericSuperclass)) {
  							return true;
  						}
  					} else if (genericSuperclass instanceof ParameterizedType) {
  						/*
  							We need to replace type parameters with concrete types
  						 */
  						ParameterizedType genericSuperclassParameterized = (ParameterizedType) genericSuperclass;
  						Type[] genericSuperclassActualTypeArguments = genericSuperclassParameterized.getActualTypeArguments();
  						for (int i = 0; i < genericSuperclassActualTypeArguments.length; i++) {
  							if (genericSuperclassActualTypeArguments[i] instanceof TypeVariable) {
  								genericSuperclassActualTypeArguments[i] = typesMap.get(genericSuperclassActualTypeArguments[i]);
  							}
  						}
  						Type genericSuperclassRawType = genericSuperclassParameterized.getRawType();
  						if (isAssignableFrom(t1, Types.newParameterizedType((Class<?>) genericSuperclassRawType,
  								genericSuperclassActualTypeArguments))) {
  							return true;
  						}
  					}
  				}
  
  				/*
  					Try the same thing with interfaces
  				 */
  				Type[] genericInterfaces = rawTypeT2.getGenericInterfaces();
  				for (Type genericInterface : genericInterfaces) {
  					if (genericInterface instanceof Class<?>) {
  						if (isAssignableFrom(t1, genericInterface)) {
  							return true;
  						}
  					} else if (genericInterface instanceof ParameterizedType) {
  						/*
  							We need to replace type parameters with concrete types
  						 */
  						ParameterizedType genericInterfaceParameterized = (ParameterizedType) genericInterface;
  						Type[] genericInterfaceActualTypeArguments = genericInterfaceParameterized.getActualTypeArguments();
  						for (int i = 0; i < genericInterfaceActualTypeArguments.length; i++) {
  							if (genericInterfaceActualTypeArguments[i] instanceof TypeVariable) {
  								genericInterfaceActualTypeArguments[i] = typesMap.get(genericInterfaceActualTypeArguments[i]);
  							}
  						}
  						Type genericInterfaceRawType = genericInterfaceParameterized.getRawType();
  						if (isAssignableFrom(t1, Types.newParameterizedType((Class<?>) genericInterfaceRawType,
  								genericInterfaceActualTypeArguments))) {
  							return true;
  						}
  					}
  				}
  
  				return false;
  
  			}
  		}
  		return false;
  	}
focal_method.class_method_signature: Types.isAssignableFrom(Type t1, Type t2)
focal_method.full_signature: public static boolean isAssignableFrom(Type t1, Type t2)
focal_method.identifier: isAssignableFrom
focal_method.invocations: checkNotNull checkNotNull equals isAssignableFrom getRawType getRawType getRawType isAssignableFrom equals getGenericSuperclass isAssignableFrom getGenericInterfaces isAssignableFrom getActualTypeArguments getTypeParameters newHashMapWithExpectedSize put getGenericSuperclass isAssignableFrom getActualTypeArguments get getRawType isAssignableFrom newParameterizedType getGenericInterfaces isAssignableFrom getActualTypeArguments get getRawType isAssignableFrom newParameterizedType
focal_method.modifiers: public static
focal_method.parameters: (Type t1, Type t2)
focal_method.return: boolean
focal_method.signature: boolean isAssignableFrom(Type t1, Type t2)