@Test
public void testParse() throws InvalidQueryException {

  List<Token> listTokens = new ArrayList<Token>();
  // foo=bar&(a<1&(b<=2|c>3)&d>=100)|e!=5&!(f=6|g=7)
  listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
  listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "foo"));
  listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "bar"));
  listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "&"));
  listTokens.add(new Token(Token.TYPE.BRACKET_OPEN, "("));
  listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "<"));
  listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "a"));
  listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "1"));
  listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "&"));
  listTokens.add(new Token(Token.TYPE.BRACKET_OPEN, "("));
  listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "<="));
  listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "b"));
  listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "2"));
  listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "|"));
  listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, ">"));
  listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "c"));
  listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "3"));
  listTokens.add(new Token(Token.TYPE.BRACKET_CLOSE, ")"));
  listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "&"));
  listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, ">="));
  listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "d"));
  listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "100"));
  listTokens.add(new Token(Token.TYPE.BRACKET_CLOSE, ")"));
  listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "|"));
  listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "!="));
  listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "e"));
  listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "5"));
  listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "&"));
  listTokens.add(new Token(Token.TYPE.LOGICAL_UNARY_OPERATOR, "!"));
  listTokens.add(new Token(Token.TYPE.BRACKET_OPEN, "("));
  listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
  listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "f"));
  listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "6"));
  listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "|"));
  listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
  listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "g"));
  listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "7"));
  listTokens.add(new Token(Token.TYPE.BRACKET_CLOSE, ")"));
  QueryParser parser = new QueryParser();
  Predicate p = parser.parse(listTokens.toArray(new Token[listTokens.size()]));
  EqualsPredicate<String> fooPred = new EqualsPredicate<String>("foo", "bar");
  LessPredicate<String> aPred = new LessPredicate<String>("a", "1");
  LessEqualsPredicate<String> bPred = new LessEqualsPredicate<String>("b", "2");
  GreaterEqualsPredicate<String> cPred = new GreaterEqualsPredicate<String>("c", "3");
  GreaterEqualsPredicate<String> dPred = new GreaterEqualsPredicate<String>("d", "100");
  NotPredicate ePred = new NotPredicate(new EqualsPredicate<String>("e", "5"));
  EqualsPredicate fPred = new EqualsPredicate<String>("f", "6");
  EqualsPredicate gPRed = new EqualsPredicate<String>("g", "7");
  OrPredicate bORcPred = new OrPredicate(bPred, cPred);
  AndPredicate aANDbORcPred = new AndPredicate(aPred, bORcPred);
  AndPredicate aANDbORcANDdPred = new AndPredicate(aANDbORcPred, dPred);
  AndPredicate fooANDaANDbORcANDdPred = new AndPredicate(fooPred, aANDbORcANDdPred);
  OrPredicate fORgPred = new OrPredicate(fPred, gPRed);
  NotPredicate NOTfORgPred = new NotPredicate(fORgPred);
  AndPredicate eANDNOTfORgPred = new AndPredicate(ePred, NOTfORgPred);
  OrPredicate rootPredicate = new OrPredicate(fooANDaANDbORcANDdPred, eANDNOTfORgPred);
  assertEquals(rootPredicate, p);
}