docs: @SuppressWarnings("unchecked")
  	private <IN1, IN2, OUT> TypeInformation<OUT> createTypeInfoFromFactory(
  			Type t, ArrayList<Type> typeHierarchy, TypeInformation<IN1> in1Type, TypeInformation<IN2> in2Type) {
  
  		final ArrayList<Type> factoryHierarchy = new ArrayList<>(typeHierarchy);
  		final TypeInfoFactory<? super OUT> factory = getClosestFactory(factoryHierarchy, t);
  		if (factory == null) {
  			return null;
  		}
  		final Type factoryDefiningType = factoryHierarchy.get(factoryHierarchy.size() - 1);
  
  		// infer possible type parameters from input
  		final Map<String, TypeInformation<?>> genericParams;
  		if (factoryDefiningType instanceof ParameterizedType) {
  			genericParams = new HashMap<>();
  			final ParameterizedType paramDefiningType = (ParameterizedType) factoryDefiningType;
  			final Type[] args = typeToClass(paramDefiningType).getTypeParameters();
  
  			final TypeInformation<?>[] subtypeInfo = createSubTypesInfo(t, paramDefiningType, factoryHierarchy, in1Type, in2Type, true);
  			assert subtypeInfo != null;
  			for (int i = 0; i < subtypeInfo.length; i++) {
  				genericParams.put(args[i].toString(), subtypeInfo[i]);
  			}
  		} else {
  			genericParams = Collections.emptyMap();
  		}
  
  		final TypeInformation<OUT> createdTypeInfo = (TypeInformation<OUT>) factory.createTypeInfo(t, genericParams);
  		if (createdTypeInfo == null) {
  			throw new InvalidTypesException("TypeInfoFactory returned invalid TypeInformation 'null'");
  		}
  		return createdTypeInfo;
  	}