@Test
  public void testSimpleCaseDual() {
    String[] constantFieldsFirst = {"1->1,2", "2->3"};
    String[] constantFieldsSecond = {"1->1,2", "2->3"};

    TypeInformation<?> type =
        new TupleTypeInfo<Tuple4<Integer, Integer, Integer, Integer>>(
            BasicTypeInfo.INT_TYPE_INFO,
            BasicTypeInfo.INT_TYPE_INFO,
            BasicTypeInfo.INT_TYPE_INFO,
            BasicTypeInfo.INT_TYPE_INFO);

    DualInputSemanticProperties dsp = new DualInputSemanticProperties();

    SemanticPropUtil.getSemanticPropsDualFromString(
        dsp, constantFieldsFirst, constantFieldsSecond, null, null, null, null, type, type, type);

    FieldSet fs = dsp.getForwardedField1(1);
    Assert.assertTrue(fs.size() == 2);
    Assert.assertTrue(fs.contains(1));
    Assert.assertTrue(fs.contains(2));

    fs = dsp.getForwardedField1(2);
    Assert.assertTrue(fs.size() == 1);
    Assert.assertTrue(fs.contains(3));
  }
  @Test
  public void testConstantExceptOneString() {
    // no spaces
    {
      String[] constantFieldsExcept = {"1"};

      TypeInformation<?> type =
          new TupleTypeInfo<Tuple3<Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(
              null, constantFieldsExcept, null, type, type);

      FieldSet fs = sp.getForwardedField(0);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(0));

      Assert.assertNull(sp.getForwardedField(1));

      fs = sp.getForwardedField(2);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(2));
    }

    // with spaces
    {
      String[] constantFieldsExcept = {" 1  "};

      TypeInformation<?> type =
          new TupleTypeInfo<Tuple3<Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(
              null, constantFieldsExcept, null, type, type);

      FieldSet fs = sp.getForwardedField(0);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(0));

      Assert.assertNull(sp.getForwardedField(1));

      fs = sp.getForwardedField(2);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(2));
    }
  }
  @Test
  public void testConstantWithArrowIndividualStrings() {
    // no spaces
    {
      String[] constantFields = {"0->0,1", "1->2"};

      TypeInformation<?> type =
          new TupleTypeInfo<Tuple3<Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(constantFields, null, null, type, type);

      FieldSet fs = sp.getForwardedField(0);
      Assert.assertTrue(fs.size() == 2);
      Assert.assertTrue(fs.contains(0));
      Assert.assertTrue(fs.contains(1));

      fs = sp.getForwardedField(1);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(2));
    }

    // with spaces
    {
      String[] constantFields = {"0 -> 0 ,   1 ", " 1     -> 2  "};

      TypeInformation<?> type =
          new TupleTypeInfo<Tuple3<Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(constantFields, null, null, type, type);

      FieldSet fs = sp.getForwardedField(0);
      Assert.assertTrue(fs.size() == 2);
      Assert.assertTrue(fs.contains(0));
      Assert.assertTrue(fs.contains(1));

      fs = sp.getForwardedField(1);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(2));
    }
  }
  @Test
  public void testConstantWildCard2() {
    // no spaces
    {
      String[] constantFields = {"1->*"};
      TypeInformation<?> type =
          new TupleTypeInfo<Tuple3<Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(constantFields, null, null, type, type);

      FieldSet fs = sp.getForwardedField(1);
      Assert.assertTrue(fs.size() == 3);
      Assert.assertTrue(fs.contains(0));
      Assert.assertTrue(fs.contains(1));
      Assert.assertTrue(fs.contains(2));
      Assert.assertTrue(sp.getForwardedField(0) == null);
      Assert.assertTrue(sp.getForwardedField(2) == null);
    }

    //		// with spaces
    //		{
    //			String[] constantFields = { "  1  -> * " };
    //			TypeInformation<?> type = new TupleTypeInfo<Tuple3<Integer, Integer,
    // Integer>>(BasicTypeInfo.INT_TYPE_INFO,
    //					BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.INT_TYPE_INFO);
    //			SingleInputSemanticProperties sp =
    // SemanticPropUtil.getSemanticPropsSingleFromString(constantFields, null, null, type, type);
    //
    //			FieldSet fs = sp.getForwardedField(1);
    //			Assert.assertTrue(fs.size() == 3);
    //			Assert.assertTrue(fs.contains(0));
    //			Assert.assertTrue(fs.contains(1));
    //			Assert.assertTrue(fs.contains(2));
    //			Assert.assertTrue(sp.getForwardedField(0) == null);
    //			Assert.assertTrue(sp.getForwardedField(2) == null);
    //		}
  }
  @Test
  public void testFieldsExceptDual() {
    String[] constantFieldsFirstExcept = {"1,2"};
    String[] constantFieldsSecond = {"0->1"};

    DualInputSemanticProperties dsp = new DualInputSemanticProperties();

    TypeInformation<?> type =
        new TupleTypeInfo<Tuple3<Integer, Integer, Integer>>(
            BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.INT_TYPE_INFO);
    SemanticPropUtil.getSemanticPropsDualFromString(
        dsp,
        null,
        constantFieldsSecond,
        constantFieldsFirstExcept,
        null,
        null,
        null,
        type,
        type,
        type);

    FieldSet fs = dsp.getForwardedField1(0);
    Assert.assertTrue(fs.size() == 1);
    Assert.assertTrue(fs.contains(0));

    fs = dsp.getForwardedField1(1);
    Assert.assertTrue(fs == null);

    fs = dsp.getForwardedField1(2);
    Assert.assertTrue(fs == null);

    fs = dsp.getForwardedField2(0);
    Assert.assertTrue(fs.size() == 1);
    Assert.assertTrue(fs.contains(1));
  }
  @Test
  public void testReadFieldsOneString() {
    // no spaces
    {
      String[] readFields = {"1,2"};

      TypeInformation<?> type =
          new TupleTypeInfo<Tuple3<Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(null, null, readFields, type, type);

      FieldSet fs = sp.getReadFields();
      Assert.assertTrue(fs.size() == 2);
      Assert.assertTrue(fs.contains(2));
      Assert.assertTrue(fs.contains(1));
    }

    // with spaces
    {
      String[] readFields = {"  1  , 2   "};

      TypeInformation<?> type =
          new TupleTypeInfo<Tuple3<Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(null, null, readFields, type, type);

      FieldSet fs = sp.getReadFields();
      Assert.assertTrue(fs.size() == 2);
      Assert.assertTrue(fs.contains(2));
      Assert.assertTrue(fs.contains(1));
    }
  }
  @Test
  public void testConstantMixedOneString() {
    // no spaces
    {
      String[] constantFields = {"2,3;0->1,4;4->0"};

      TypeInformation<?> type =
          new TupleTypeInfo<Tuple5<Integer, Integer, Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(constantFields, null, null, type, type);

      FieldSet fs = sp.getForwardedField(0);
      Assert.assertTrue(fs.size() == 2);
      Assert.assertTrue(fs.contains(1));
      Assert.assertTrue(fs.contains(4));

      fs = sp.getForwardedField(2);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(2));

      fs = sp.getForwardedField(3);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(3));

      fs = sp.getForwardedField(4);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(0));
    }

    // with spaces
    {
      String[] constantFields = {" 2  ,  3   ;  0 -> 1  , 4 ; 4 ->  0"};

      TypeInformation<?> type =
          new TupleTypeInfo<Tuple5<Integer, Integer, Integer, Integer, Integer>>(
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO,
              BasicTypeInfo.INT_TYPE_INFO);
      SingleInputSemanticProperties sp =
          SemanticPropUtil.getSemanticPropsSingleFromString(constantFields, null, null, type, type);

      FieldSet fs = sp.getForwardedField(0);
      Assert.assertTrue(fs.size() == 2);
      Assert.assertTrue(fs.contains(1));
      Assert.assertTrue(fs.contains(4));

      fs = sp.getForwardedField(2);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(2));

      fs = sp.getForwardedField(3);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(3));

      fs = sp.getForwardedField(4);
      Assert.assertTrue(fs.size() == 1);
      Assert.assertTrue(fs.contains(0));
    }
  }