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();

}