class SemanticPropUtil {

	public static DualInputSemanticProperties createProjectionPropertiesDual(
		int[] fields, boolean[] isFromFirst, TypeInformation<?> inType1, TypeInformation<?> inType2) {
		DualInputSemanticProperties dsp = new DualInputSemanticProperties();

		int[] sourceOffsets1;
		if (inType1 instanceof TupleTypeInfo<?>) {
			sourceOffsets1 = new int[inType1.getArity()];
			sourceOffsets1[0] = 0;
			for (int i = 1; i < inType1.getArity(); i++) {
				sourceOffsets1[i] = ((TupleTypeInfo<?>) inType1).getTypeAt(i - 1).getTotalFields() + sourceOffsets1[i - 1];
			}
		} else {
			sourceOffsets1 = new int[]{0};
		}

		int[] sourceOffsets2;
		if (inType2 instanceof TupleTypeInfo<?>) {
			sourceOffsets2 = new int[inType2.getArity()];
			sourceOffsets2[0] = 0;
			for (int i = 1; i < inType2.getArity(); i++) {
				sourceOffsets2[i] = ((TupleTypeInfo<?>) inType2).getTypeAt(i - 1).getTotalFields() + sourceOffsets2[i - 1];
			}
		} else {
			sourceOffsets2 = new int[]{0};
		}

		int targetOffset = 0;
		for (int i = 0; i < fields.length; i++) {
			int sourceOffset;
			int numFieldsToCopy;
			int input;
			if (isFromFirst[i]) {
				input = 0;
				if (fields[i] == -1) {
					sourceOffset = 0;
					numFieldsToCopy = inType1.getTotalFields();
				} else {
					sourceOffset = sourceOffsets1[fields[i]];
					numFieldsToCopy = ((TupleTypeInfo<?>) inType1).getTypeAt(fields[i]).getTotalFields();
				}
			} else {
				input = 1;
				if (fields[i] == -1) {
					sourceOffset = 0;
					numFieldsToCopy = inType2.getTotalFields();
				} else {
					sourceOffset = sourceOffsets2[fields[i]];
					numFieldsToCopy = ((TupleTypeInfo<?>) inType2).getTypeAt(fields[i]).getTotalFields();
				}
			}

			for (int j = 0; j < numFieldsToCopy; j++) {
				dsp.addForwardedField(input, sourceOffset + j, targetOffset + j);
			}
			targetOffset += numFieldsToCopy;
		}

		return dsp;
	}

	private  SemanticPropUtil();

}