static TimelineFilterList parseRelationFilters(String expr)
      throws TimelineParseException {
    return parseFilters(new TimelineParserForRelationFilters(expr,
        TimelineParseConstants.COMMA_CHAR,
        TimelineParseConstants.COLON_DELIMITER));
  }
@Test
  void testRelationFiltersParsing() throws Exception {
    String expr = "type1:entity11,type2:entity21:entity22";
    TimelineFilterList expectedList = new TimelineFilterList(
        new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
            "type1", Sets.newHashSet((Object) "entity11")),
        new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
            "type2", Sets.newHashSet((Object) "entity21", "entity22"))
    );
    verifyFilterList(expr, TimelineReaderWebServicesUtils.
        parseRelationFilters(expr), expectedList);

    expr = "(type1:entity11,type2:entity21:entity22)";
    verifyFilterList(expr, TimelineReaderWebServicesUtils.
        parseRelationFilters(expr), expectedList);

    expr = "(type1:entity11,type2:entity21:entity22) OR (type3:entity31:" +
        "entity32:entity33,type1:entity11:entity12)";
    expectedList = new TimelineFilterList(Operator.OR,
        new TimelineFilterList(
            new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                "type1", Sets.newHashSet((Object) "entity11")),
            new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                "type2", Sets.newHashSet((Object) "entity21", "entity22"))
        ),
        new TimelineFilterList(
            new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                "type3", Sets.newHashSet(
                    (Object) "entity31", "entity32", "entity33")),
            new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                "type1", Sets.newHashSet((Object) "entity11", "entity12"))
        )
    );
    verifyFilterList(expr, TimelineReaderWebServicesUtils.
        parseRelationFilters(expr), expectedList);

    expr = "!(type1:entity11,type2:entity21:entity22,type5:entity51) OR " +
        "(type3:entity31:entity32:entity33,type1:entity11:entity12)";

    expectedList = new TimelineFilterList(Operator.OR,
        new TimelineFilterList(
            new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                "type1", Sets.newHashSet((Object) "entity11")),
            new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                "type2", Sets.newHashSet((Object) "entity21", "entity22")),
            new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                "type5", Sets.newHashSet((Object) "entity51"))
        ),
        new TimelineFilterList(
            new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                "type3", Sets.newHashSet(
                    (Object) "entity31", "entity32", "entity33")),
            new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                "type1", Sets.newHashSet((Object) "entity11", "entity12"))
        )
    );
    verifyFilterList(expr, TimelineReaderWebServicesUtils.
        parseRelationFilters(expr), expectedList);

    expr = "(((!(type1:entity11,type2:entity21:entity22,type5:entity51) OR " +
        "(type3:entity31:entity32:entity33,type1:entity11:entity12)) AND " +
        "(!(type11:entity111) OR !(type4:entity43:entity44:entity47:entity49," +
        "type7:entity71))) OR ((type2:entity2,type8:entity88) AND t9:e:e1))";
    expectedList = new TimelineFilterList(Operator.OR,
        new TimelineFilterList(
            new TimelineFilterList(Operator.OR,
                new TimelineFilterList(
                    new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                        "type1", Sets.newHashSet((Object) "entity11")),
                    new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                        "type2", Sets.newHashSet(
                            (Object) "entity21", "entity22")),
                    new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                        "type5", Sets.newHashSet((Object) "entity51"))
                ),
                new TimelineFilterList(
                    new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                        "type3", Sets.newHashSet(
                            (Object) "entity31", "entity32", "entity33")),
                    new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                        "type1", Sets.newHashSet(
                            (Object) "entity11", "entity12"))
                )
            ),
            new TimelineFilterList(Operator.OR,
                new TimelineFilterList(
                    new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                        "type11", Sets.newHashSet((Object) "entity111"))
                ),
                new TimelineFilterList(
                    new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                        "type4", Sets.newHashSet((Object) "entity43", "entity44",
                            "entity47", "entity49")),
                    new TimelineKeyValuesFilter(TimelineCompareOp.NOT_EQUAL,
                        "type7", Sets.newHashSet((Object) "entity71"))
                )
            )
        ),
        new TimelineFilterList(
            new TimelineFilterList(
                new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                    "type2", Sets.newHashSet((Object) "entity2")),
                new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL,
                    "type8", Sets.newHashSet((Object) "entity88"))
            ),
            new TimelineKeyValuesFilter(TimelineCompareOp.EQUAL, "t9",
                Sets.newHashSet((Object) "e", "e1"))
        )
    );
    verifyFilterList(expr, TimelineReaderWebServicesUtils.
        parseRelationFilters(expr), expectedList);

    expr = "   (   (  (   !   (   type1:entity11  ,  type2:entity21:entity22" +
        "  ,  type5:entity51  )   OR  (   type3:entity31:entity32:entity33  " +
        "     ,   type1:entity11:entity12)) AND (!(  type11:entity111  )  OR " +
        "    !   (   type4:entity43:entity44:entity47:entity49 , " +
        "type7:entity71  )  )  ) OR  (  (  type2:entity2 , type8:entity88) " +
        "AND  t9:e:e1 )    ) ";
    verifyFilterList(expr, TimelineReaderWebServicesUtils.
        parseRelationFilters(expr), expectedList);

    expr = "(((!(type1 : entity11,type2:entity21:entity22,type5:entity51) OR " +
        "(type3:entity31:entity32:entity33,type1:entity11:entity12)) AND " +
        "(!(type11:entity111) OR !(type4:entity43:entity44:entity47:entity49," +
        "type7:entity71))) OR ((type2:entity2,type8:entity88) AND t9:e:e1))";
    try {
      TimelineReaderWebServicesUtils.parseRelationFilters(expr);
      fail("Space not allowed in relation expression. Exception should have " +
          "been thrown");
    } catch (TimelineParseException e) {
    }
  }