public static void getSemanticPropsSingleFromString(
            SingleInputSemanticProperties result,
            String[] forwarded,
            String[] nonForwarded,
            String[] readSet,
            TypeInformation<?> inType,
            TypeInformation<?> outType) {
        getSemanticPropsSingleFromString(
                result, forwarded, nonForwarded, readSet, inType, outType, false);
    }
@Test
    void testForwardedNestedTuples() {
        String[] forwardedFields = {"f0->f0.f0; f1->f0.f1; f2->f0.f2"};
        SingleInputSemanticProperties sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, threeIntTupleType, nestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 0)).contains(0);
        assertThat(sp.getForwardingTargetFields(0, 1)).contains(1);
        assertThat(sp.getForwardingTargetFields(0, 2)).contains(2);

        forwardedFields[0] = "f0.f0->f1.f0.f2; f0.f1->f2; f2->f1.f2; f1->f0";
        sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, nestedTupleType, deepNestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 0)).contains(3);
        assertThat(sp.getForwardingTargetFields(0, 1)).contains(6);
        assertThat(sp.getForwardingTargetFields(0, 4)).contains(5);
        assertThat(sp.getForwardingTargetFields(0, 3)).contains(0);

        forwardedFields[0] = "0.0->1.0.2; 0.1->2; 2->1.2; 1->0";
        sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, nestedTupleType, deepNestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 0)).contains(3);
        assertThat(sp.getForwardingTargetFields(0, 1)).contains(6);
        assertThat(sp.getForwardingTargetFields(0, 4)).contains(5);
        assertThat(sp.getForwardingTargetFields(0, 3)).contains(0);

        forwardedFields[0] = "f1.f0.*->f0.*; f0->f2";
        sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, deepNestedTupleType, nestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 1)).contains(0);
        assertThat(sp.getForwardingTargetFields(0, 2)).contains(1);
        assertThat(sp.getForwardingTargetFields(0, 3)).contains(2);
        assertThat(sp.getForwardingTargetFields(0, 0)).contains(4);

        forwardedFields[0] = "1.0.*->0.*; 0->2";
        sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, deepNestedTupleType, nestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 1)).contains(0);
        assertThat(sp.getForwardingTargetFields(0, 2)).contains(1);
        assertThat(sp.getForwardingTargetFields(0, 3)).contains(2);
        assertThat(sp.getForwardingTargetFields(0, 0)).contains(4);

        forwardedFields[0] = "f1.f0->f0; f0->f2";
        sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, deepNestedTupleType, nestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 1)).contains(0);
        assertThat(sp.getForwardingTargetFields(0, 2)).contains(1);
        assertThat(sp.getForwardingTargetFields(0, 3)).contains(2);
        assertThat(sp.getForwardingTargetFields(0, 0)).contains(4);

        forwardedFields[0] = "1.0->0; 0->2";
        sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, deepNestedTupleType, nestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 1)).contains(0);
        assertThat(sp.getForwardingTargetFields(0, 2)).contains(1);
        assertThat(sp.getForwardingTargetFields(0, 3)).contains(2);
        assertThat(sp.getForwardingTargetFields(0, 0)).contains(4);

        forwardedFields[0] = "f1.f0.f1; f1.f1; f2";
        sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, deepNestedTupleType, deepNestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 2)).contains(2);
        assertThat(sp.getForwardingTargetFields(0, 4)).contains(4);
        assertThat(sp.getForwardingTargetFields(0, 6)).contains(6);
        assertThat(sp.getForwardingTargetFields(0, 0)).isEmpty();
        assertThat(sp.getForwardingTargetFields(0, 1)).isEmpty();
        assertThat(sp.getForwardingTargetFields(0, 3)).isEmpty();
        assertThat(sp.getForwardingTargetFields(0, 5)).isEmpty();

        forwardedFields[0] = "f1.f0.*; f1.f2";
        sp = new SingleInputSemanticProperties();
        SemanticPropUtil.getSemanticPropsSingleFromString(
                sp, forwardedFields, null, null, deepNestedTupleType, deepNestedTupleType);
        assertThat(sp.getForwardingTargetFields(0, 1)).contains(1);
        assertThat(sp.getForwardingTargetFields(0, 2)).contains(2);
        assertThat(sp.getForwardingTargetFields(0, 3)).contains(3);
        assertThat(sp.getForwardingTargetFields(0, 5)).contains(5);
        assertThat(sp.getForwardingTargetFields(0, 0)).isEmpty();
        assertThat(sp.getForwardingTargetFields(0, 4)).isEmpty();
        assertThat(sp.getForwardingTargetFields(0, 6)).isEmpty();
    }