This is an automated email from the ASF dual-hosted git repository.

vavrtom pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-broker-j.git


The following commit(s) were added to refs/heads/main by this push:
     new 3223e43f86 QPID-8674 - [Broker-J] Jms Selector Parsing - multiple 
AND's (#249)
3223e43f86 is described below

commit 3223e43f86159bba9c269b98325c66976b584a85
Author: Daniil Kirilyuk <[email protected]>
AuthorDate: Fri Jan 10 09:26:07 2025 +0100

    QPID-8674 - [Broker-J] Jms Selector Parsing - multiple AND's (#249)
---
 broker-core/src/main/grammar/SelectorParser.jj     | 273 +++----
 .../server/filter/selector/SelectorParser.java     | 907 +++++++++++----------
 .../server/filter/JMSSelectorFilterSyntaxTest.java | 278 ++++++-
 3 files changed, 865 insertions(+), 593 deletions(-)

diff --git a/broker-core/src/main/grammar/SelectorParser.jj 
b/broker-core/src/main/grammar/SelectorParser.jj
index 4271907cd9..63f369a1dc 100644
--- a/broker-core/src/main/grammar/SelectorParser.jj
+++ b/broker-core/src/main/grammar/SelectorParser.jj
@@ -114,8 +114,6 @@ public class SelectorParser<E>
         }
         throw new ParseException("Expression will not result in a boolean 
value: " + value);
     }
-
-
 }
 
 PARSER_END(SelectorParser)
@@ -202,37 +200,31 @@ Expression orExpression() :
     Expression right;
 }
 {
+    left = andExpression()
     (
-        left = andExpression()
-        (
-            <OR> right = andExpression()
-            {
-                left = LogicExpression.createOR(asBooleanExpression(left), 
asBooleanExpression(right));
-            }
-        )*
-    )
+        <OR> right = andExpression()
+        {
+            left = LogicExpression.createOR(asBooleanExpression(left), 
asBooleanExpression(right));
+        }
+    )*
     {
         return left;
     }
-
 }
 
-
 Expression andExpression() :
 {
     Expression left;
     Expression right;
 }
 {
+    left = equalityExpression()
     (
-        left = equalityExpression()
-        (
-            <AND> right = equalityExpression()
-            {
-                left = LogicExpression.createAND(asBooleanExpression(left), 
asBooleanExpression(right));
-            }
-        )*
-    )
+        <AND> right = equalityExpression()
+        {
+            left = LogicExpression.createAND(asBooleanExpression(left), 
asBooleanExpression(right));
+        }
+    )*
     {
         return left;
     }
@@ -244,32 +236,28 @@ Expression equalityExpression() :
     Expression right;
 }
 {
+    left = comparisonExpression()
     (
-        left = comparisonExpression()
-        (
-
-            "=" right = comparisonExpression()
-            {
-                left = ComparisonExpression.createEqual(left, right);
-            }
-            |
-            "<>" right = comparisonExpression()
-            {
-                left = ComparisonExpression.createNotEqual(left, right);
-            }
-            |
-            LOOKAHEAD(2)
-            <IS> <NULL>
-            {
-                left = ComparisonExpression.createIsNull(left);
-            }
-            |
-            <IS> <NOT> <NULL>
-            {
-                left = ComparisonExpression.createIsNotNull(left);
-            }
-        )*
-    )
+        LOOKAHEAD(2) "=" right = comparisonExpression()
+        {
+            left = ComparisonExpression.createEqual(left, right);
+        }
+        |
+        "<>" right = comparisonExpression()
+        {
+            left = ComparisonExpression.createNotEqual(left, right);
+        }
+        |
+        LOOKAHEAD(2) <IS> <NULL>
+        {
+            left = ComparisonExpression.createIsNull(left);
+        }
+        |
+        <IS> <NOT> <NULL>
+        {
+            left = ComparisonExpression.createIsNotNull(left);
+        }
+    )*
     {
         return left;
     }
@@ -286,102 +274,83 @@ Expression comparisonExpression() :
        ArrayList list;
 }
 {
+    left = addExpression()
     (
-        left = addExpression()
-        (
-
-                ">" right = addExpression()
-                {
-                    left = ComparisonExpression.createGreaterThan(left, right);
-                }
-            |
-                ">=" right = addExpression()
-                {
-                    left = ComparisonExpression.createGreaterThanEqual(left, 
right);
-                }
-            |
-                "<" right = addExpression()
-                {
-                    left = ComparisonExpression.createLessThan(left, right);
-                }
-            |
-                "<=" right = addExpression()
-                {
-                    left = ComparisonExpression.createLessThanEqual(left, 
right);
-                }
-           |
-                               {
-                                       u=null;
-                               }
-                       <LIKE> t = stringLiteral()
-                               [ <ESCAPE> u = stringLiteral() ]
-                       {
-                    left = ComparisonExpression.createLike(left, t, u);
-                       }
-           |
-                       LOOKAHEAD(2)
-                               {
-                                       u=null;
-                               }
-                       <NOT> <LIKE> t = stringLiteral() [ <ESCAPE> u = 
stringLiteral() ]
-                       {
-                    left = ComparisonExpression.createNotLike(left, t, u);
-                       }
-            |
-                       <BETWEEN> low = addExpression() <AND> high = 
addExpression()
-                       {
-                                       left = 
ComparisonExpression.createBetween(left, low, high);
-                       }
-               |
-                       LOOKAHEAD(2)
-                       <NOT> <BETWEEN> low = addExpression() <AND> high = 
addExpression()
-                       {
-                                       left = 
ComparisonExpression.createNotBetween(left, low, high);
-                       }
-            |
-                               <IN>
-                       "("
-                           t = stringLiteral()
-                           {
-                                   list = new ArrayList();
-                                   list.add( t );
-                           }
-                               (
-                                       ","
-                                   t = stringLiteral()
-                                   {
-                                           list.add( t );
-                                   }
-
-                               )*
-                       ")"
-                       {
-                          left = ComparisonExpression.createInFilter(left, 
list, false );
-                       }
-            |
-                       LOOKAHEAD(2)
-                   <NOT> <IN>
-                       "("
-                           t = stringLiteral()
-                           {
-                                   list = new ArrayList();
-                                   list.add( t );
-                           }
-                               (
-                                       ","
-                                   t = stringLiteral()
-                                   {
-                                           list.add( t );
-                                   }
-
-                               )*
-                       ")"
-                       {
-                          left = ComparisonExpression.createNotInFilter(left, 
list, false);
-                       }
-
-        )*
-    )
+        LOOKAHEAD(2) ">" right = addExpression()
+        {
+            left = ComparisonExpression.createGreaterThan(left, right);
+        }
+        |
+        ">=" right = addExpression()
+        {
+            left = ComparisonExpression.createGreaterThanEqual(left, right);
+        }
+        |
+        "<" right = addExpression()
+        {
+            left = ComparisonExpression.createLessThan(left, right);
+        }
+        |
+        "<=" right = addExpression()
+        {
+            left = ComparisonExpression.createLessThanEqual(left, right);
+        }
+        |
+        {
+            u=null;
+        }
+        <LIKE> t = stringLiteral() [ <ESCAPE> u = stringLiteral() ]
+        {
+            left = ComparisonExpression.createLike(left, t, u);
+        }
+        |
+        LOOKAHEAD(2)
+        {
+            u=null;
+        }
+        <NOT> <LIKE> t = stringLiteral() [ <ESCAPE> u = stringLiteral() ]
+        {
+            left = ComparisonExpression.createNotLike(left, t, u);
+        }
+        |
+        <BETWEEN> low = addExpression() <AND> high = addExpression()
+        {
+            left = ComparisonExpression.createBetween(left, low, high);
+        }
+        |
+        LOOKAHEAD(2) <NOT> <BETWEEN> low = addExpression() <AND> high = 
addExpression()
+        {
+            left = ComparisonExpression.createNotBetween(left, low, high);
+        }
+        |
+        <IN> "(" t = stringLiteral()
+        {
+            list = new ArrayList();
+            list.add( t );
+        }
+        ( "," t = stringLiteral()
+            {
+                list.add( t );
+            }
+        )* ")"
+        {
+            left = ComparisonExpression.createInFilter(left, list, false );
+        }
+        |
+        LOOKAHEAD(2) <NOT> <IN> "(" t = stringLiteral()
+        {
+            list = new ArrayList();
+            list.add( t );
+        }
+        ( "," t = stringLiteral()
+        {
+            list.add( t );
+        }
+        )* ")"
+        {
+            left = ComparisonExpression.createNotInFilter(left, list, false);
+        }
+    )*
     {
         return left;
     }
@@ -407,7 +376,6 @@ Expression addExpression() :
                    left = ArithmeticExpression.createMinus(left, right);
                }
         )
-
     )*
     {
         return left;
@@ -422,7 +390,7 @@ Expression multExpr() :
 {
     left = unaryExpr()
     (
-        "*" right = unaryExpr()
+        LOOKAHEAD(2) "*" right = unaryExpr()
         {
                left = ArithmeticExpression.createMultiply(left, right);
         }
@@ -436,14 +404,12 @@ Expression multExpr() :
         {
                left = ArithmeticExpression.createMod(left, right);
         }
-
     )*
     {
         return left;
     }
 }
 
-
 Expression unaryExpr() :
 {
     String s=null;
@@ -451,15 +417,19 @@ Expression unaryExpr() :
 }
 {
        (
-               LOOKAHEAD( "+" unaryExpr() )
-           "+" left=unaryExpr()
+           LOOKAHEAD("+" unaryExpr()) "+" left = unaryExpr()
            |
-           "-" left=unaryExpr()
+           "-" left = unaryExpr()
            {
                left = UnaryExpression.createNegate(left);
            }
            |
-           <NOT> left=orExpression()
+        LOOKAHEAD(<NOT> equalityExpression()) <NOT> left = equalityExpression()
+        {
+            left = UnaryExpression.createNOT( asBooleanExpression(left) );
+        }
+        |
+           LOOKAHEAD(<NOT> unaryExpr()) <NOT> left = unaryExpr()
            {
                    left = UnaryExpression.createNOT( asBooleanExpression(left) 
);
            }
@@ -469,7 +439,6 @@ Expression unaryExpr() :
     {
         return left;
     }
-
 }
 
 Expression primaryExpr() :
@@ -482,15 +451,13 @@ Expression primaryExpr() :
         |
         left = variable()
         |
-        "(" left = orExpression() ")"
+        LOOKAHEAD(2) "(" left = orExpression() ")"
     )
     {
         return left;
     }
 }
 
-
-
 ConstantExpression literal() :
 {
     Token t;
@@ -610,8 +577,6 @@ PropertyExpression variable() :
             }
             return _factory.createPropertyExpression(rc.toString());
         }
-
-
     )
     {
         return left;
diff --git 
a/broker-core/src/main/java/org/apache/qpid/server/filter/selector/SelectorParser.java
 
b/broker-core/src/main/java/org/apache/qpid/server/filter/selector/SelectorParser.java
index 80082f52c8..009b6ecb8a 100644
--- 
a/broker-core/src/main/java/org/apache/qpid/server/filter/selector/SelectorParser.java
+++ 
b/broker-core/src/main/java/org/apache/qpid/server/filter/selector/SelectorParser.java
@@ -100,7 +100,7 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
       }
       jj_consume_token(OR);
       right = andExpression();
-                left = LogicExpression.createOR(asBooleanExpression(left), 
asBooleanExpression(right));
+            left = LogicExpression.createOR(asBooleanExpression(left), 
asBooleanExpression(right));
     }
         {if (true) return left;}
     throw new Error("Missing return statement in function");
@@ -121,7 +121,7 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
       }
       jj_consume_token(AND);
       right = equalityExpression();
-                left = LogicExpression.createAND(asBooleanExpression(left), 
asBooleanExpression(right));
+            left = LogicExpression.createAND(asBooleanExpression(left), 
asBooleanExpression(right));
     }
         {if (true) return left;}
     throw new Error("Missing return statement in function");
@@ -142,33 +142,34 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
       default:
         break label_3;
       }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 27:
+      if (jj_2_1(2)) {
         jj_consume_token(27);
         right = comparisonExpression();
-                left = ComparisonExpression.createEqual(left, right);
-        break;
-      case 28:
-        jj_consume_token(28);
-        right = comparisonExpression();
-                left = ComparisonExpression.createNotEqual(left, right);
-        break;
-      default:
-        if (jj_2_1(2)) {
-          jj_consume_token(IS);
-          jj_consume_token(NULL);
-                left = ComparisonExpression.createIsNull(left);
-        } else {
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case IS:
+            left = ComparisonExpression.createEqual(left, right);
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 28:
+          jj_consume_token(28);
+          right = comparisonExpression();
+            left = ComparisonExpression.createNotEqual(left, right);
+          break;
+        default:
+          if (jj_2_2(2)) {
             jj_consume_token(IS);
-            jj_consume_token(NOT);
             jj_consume_token(NULL);
-                left = ComparisonExpression.createIsNotNull(left);
-            break;
-          default:
-            jj_consume_token(-1);
-            throw new ParseException();
+            left = ComparisonExpression.createIsNull(left);
+          } else {
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case IS:
+              jj_consume_token(IS);
+              jj_consume_token(NOT);
+              jj_consume_token(NULL);
+            left = ComparisonExpression.createIsNotNull(left);
+              break;
+            default:
+              jj_consume_token(-1);
+              throw new ParseException();
+            }
           }
         }
       }
@@ -202,45 +203,29 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
       default:
         break label_4;
       }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 29:
+      if (jj_2_3(2)) {
         jj_consume_token(29);
         right = addExpression();
-                    left = ComparisonExpression.createGreaterThan(left, right);
-        break;
-      case 30:
-        jj_consume_token(30);
-        right = addExpression();
-                    left = ComparisonExpression.createGreaterThanEqual(left, 
right);
-        break;
-      case 31:
-        jj_consume_token(31);
-        right = addExpression();
-                    left = ComparisonExpression.createLessThan(left, right);
-        break;
-      case 32:
-        jj_consume_token(32);
-        right = addExpression();
-                    left = ComparisonExpression.createLessThanEqual(left, 
right);
-        break;
-      case LIKE:
-                                        u=null;
-        jj_consume_token(LIKE);
-        t = stringLiteral();
+            left = ComparisonExpression.createGreaterThan(left, right);
+      } else {
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case ESCAPE:
-          jj_consume_token(ESCAPE);
-          u = stringLiteral();
+        case 30:
+          jj_consume_token(30);
+          right = addExpression();
+            left = ComparisonExpression.createGreaterThanEqual(left, right);
           break;
-        default:
-          ;
-        }
-                    left = ComparisonExpression.createLike(left, t, u);
-        break;
-      default:
-        if (jj_2_2(2)) {
-                                        u=null;
-          jj_consume_token(NOT);
+        case 31:
+          jj_consume_token(31);
+          right = addExpression();
+            left = ComparisonExpression.createLessThan(left, right);
+          break;
+        case 32:
+          jj_consume_token(32);
+          right = addExpression();
+            left = ComparisonExpression.createLessThanEqual(left, right);
+          break;
+        case LIKE:
+            u=null;
           jj_consume_token(LIKE);
           t = stringLiteral();
           switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -251,74 +236,91 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
           default:
             ;
           }
-                    left = ComparisonExpression.createNotLike(left, t, u);
-        } else {
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case BETWEEN:
-            jj_consume_token(BETWEEN);
-            low = addExpression();
-            jj_consume_token(AND);
-            high = addExpression();
-                                        left = 
ComparisonExpression.createBetween(left, low, high);
-            break;
-          default:
-            if (jj_2_3(2)) {
-              jj_consume_token(NOT);
+            left = ComparisonExpression.createLike(left, t, u);
+          break;
+        default:
+          if (jj_2_4(2)) {
+            u=null;
+            jj_consume_token(NOT);
+            jj_consume_token(LIKE);
+            t = stringLiteral();
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case ESCAPE:
+              jj_consume_token(ESCAPE);
+              u = stringLiteral();
+              break;
+            default:
+              ;
+            }
+            left = ComparisonExpression.createNotLike(left, t, u);
+          } else {
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case BETWEEN:
               jj_consume_token(BETWEEN);
               low = addExpression();
               jj_consume_token(AND);
               high = addExpression();
-                                        left = 
ComparisonExpression.createNotBetween(left, low, high);
-            } else {
-              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-              case IN:
-                jj_consume_token(IN);
-                jj_consume_token(33);
-                t = stringLiteral();
-                                    list = new ArrayList();
-                                    list.add( t );
-                label_5:
-                while (true) {
-                  switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-                  case 34:
-                    ;
-                    break;
-                  default:
-                    break label_5;
-                  }
-                  jj_consume_token(34);
-                  t = stringLiteral();
-                                            list.add( t );
-                }
-                jj_consume_token(35);
-                           left = ComparisonExpression.createInFilter(left, 
list, false );
-                break;
-              default:
-                if (jj_2_4(2)) {
-                  jj_consume_token(NOT);
+            left = ComparisonExpression.createBetween(left, low, high);
+              break;
+            default:
+              if (jj_2_5(2)) {
+                jj_consume_token(NOT);
+                jj_consume_token(BETWEEN);
+                low = addExpression();
+                jj_consume_token(AND);
+                high = addExpression();
+            left = ComparisonExpression.createNotBetween(left, low, high);
+              } else {
+                switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+                case IN:
                   jj_consume_token(IN);
                   jj_consume_token(33);
                   t = stringLiteral();
-                                    list = new ArrayList();
-                                    list.add( t );
-                  label_6:
+            list = new ArrayList();
+            list.add( t );
+                  label_5:
                   while (true) {
                     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
                     case 34:
                       ;
                       break;
                     default:
-                      break label_6;
+                      break label_5;
                     }
                     jj_consume_token(34);
                     t = stringLiteral();
-                                            list.add( t );
+                list.add( t );
                   }
                   jj_consume_token(35);
-                           left = ComparisonExpression.createNotInFilter(left, 
list, false);
-                } else {
-                  jj_consume_token(-1);
-                  throw new ParseException();
+            left = ComparisonExpression.createInFilter(left, list, false );
+                  break;
+                default:
+                  if (jj_2_6(2)) {
+                    jj_consume_token(NOT);
+                    jj_consume_token(IN);
+                    jj_consume_token(33);
+                    t = stringLiteral();
+            list = new ArrayList();
+            list.add( t );
+                    label_6:
+                    while (true) {
+                      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+                      case 34:
+                        ;
+                        break;
+                      default:
+                        break label_6;
+                      }
+                      jj_consume_token(34);
+                      t = stringLiteral();
+            list.add( t );
+                    }
+                    jj_consume_token(35);
+            left = ComparisonExpression.createNotInFilter(left, list, false);
+                  } else {
+                    jj_consume_token(-1);
+                    throw new ParseException();
+                  }
                 }
               }
             }
@@ -336,7 +338,7 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
     left = multExpr();
     label_7:
     while (true) {
-      if (jj_2_5(2147483647)) {
+      if (jj_2_7(2147483647)) {
         ;
       } else {
         break label_7;
@@ -376,25 +378,26 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
       default:
         break label_8;
       }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 38:
+      if (jj_2_8(2)) {
         jj_consume_token(38);
         right = unaryExpr();
                 left = ArithmeticExpression.createMultiply(left, right);
-        break;
-      case 39:
-        jj_consume_token(39);
-        right = unaryExpr();
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 39:
+          jj_consume_token(39);
+          right = unaryExpr();
                 left = ArithmeticExpression.createDivide(left, right);
-        break;
-      case 40:
-        jj_consume_token(40);
-        right = unaryExpr();
+          break;
+        case 40:
+          jj_consume_token(40);
+          right = unaryExpr();
                 left = ArithmeticExpression.createMod(left, right);
-        break;
-      default:
-        jj_consume_token(-1);
-        throw new ParseException();
+          break;
+        default:
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
       }
     }
         {if (true) return left;}
@@ -404,7 +407,7 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
   final public Expression unaryExpr() throws ParseException {
     String s=null;
     Expression left=null;
-    if (jj_2_6(2147483647)) {
+    if (jj_2_9(2147483647)) {
       jj_consume_token(36);
       left = unaryExpr();
     } else {
@@ -414,27 +417,35 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
         left = unaryExpr();
                 left = UnaryExpression.createNegate(left);
         break;
-      case NOT:
-        jj_consume_token(NOT);
-        left = orExpression();
-                    left = UnaryExpression.createNOT( 
asBooleanExpression(left) );
-        break;
-      case TRUE:
-      case FALSE:
-      case NULL:
-      case DECIMAL_LITERAL:
-      case HEX_LITERAL:
-      case OCTAL_LITERAL:
-      case FLOATING_POINT_LITERAL:
-      case STRING_LITERAL:
-      case ID:
-      case QUOTED_ID:
-      case 33:
-        left = primaryExpr();
-        break;
       default:
-        jj_consume_token(-1);
-        throw new ParseException();
+        if (jj_2_10(2147483647)) {
+          jj_consume_token(NOT);
+          left = equalityExpression();
+            left = UnaryExpression.createNOT( asBooleanExpression(left) );
+        } else if (jj_2_11(2147483647)) {
+          jj_consume_token(NOT);
+          left = unaryExpr();
+                    left = UnaryExpression.createNOT( 
asBooleanExpression(left) );
+        } else {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case TRUE:
+          case FALSE:
+          case NULL:
+          case DECIMAL_LITERAL:
+          case HEX_LITERAL:
+          case OCTAL_LITERAL:
+          case FLOATING_POINT_LITERAL:
+          case STRING_LITERAL:
+          case ID:
+          case QUOTED_ID:
+          case 33:
+            left = primaryExpr();
+            break;
+          default:
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+        }
       }
     }
         {if (true) return left;}
@@ -458,14 +469,15 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
     case QUOTED_ID:
       left = variable();
       break;
-    case 33:
-      jj_consume_token(33);
-      left = orExpression();
-      jj_consume_token(35);
-      break;
     default:
-      jj_consume_token(-1);
-      throw new ParseException();
+      if (jj_2_12(2)) {
+        jj_consume_token(33);
+        left = orExpression();
+        jj_consume_token(35);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
     }
         {if (true) return left;}
     throw new Error("Missing return statement in function");
@@ -602,493 +614,550 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
     catch(LookaheadSuccess ls) { return true; }
   }
 
-  private boolean jj_3R_12() {
-    if (jj_scan_token(36)) return true;
-    if (jj_3R_10()) return true;
-    return false;
+  private boolean jj_2_7(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_7(); }
+    catch(LookaheadSuccess ls) { return true; }
   }
 
-  private boolean jj_3R_55() {
-    if (jj_scan_token(IN)) return true;
-    if (jj_scan_token(33)) return true;
-    if (jj_3R_47()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_60()) { jj_scanpos = xsp; break; }
-    }
-    if (jj_scan_token(35)) return true;
-    return false;
+  private boolean jj_2_8(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_8(); }
+    catch(LookaheadSuccess ls) { return true; }
   }
 
-  private boolean jj_3R_46() {
-    if (jj_scan_token(IS)) return true;
-    if (jj_scan_token(NOT)) return true;
-    if (jj_scan_token(NULL)) return true;
-    return false;
+  private boolean jj_2_9(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_9(); }
+    catch(LookaheadSuccess ls) { return true; }
   }
 
-  private boolean jj_3R_13() {
-    if (jj_scan_token(37)) return true;
-    if (jj_3R_10()) return true;
-    return false;
+  private boolean jj_2_10(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_10(); }
+    catch(LookaheadSuccess ls) { return true; }
   }
 
-  private boolean jj_3R_39() {
-    if (jj_scan_token(NULL)) return true;
-    return false;
+  private boolean jj_2_11(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_11(); }
+    catch(LookaheadSuccess ls) { return true; }
   }
 
-  private boolean jj_3_1() {
-    if (jj_scan_token(IS)) return true;
-    if (jj_scan_token(NULL)) return true;
-    return false;
+  private boolean jj_2_12(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_12(); }
+    catch(LookaheadSuccess ls) { return true; }
   }
 
-  private boolean jj_3R_10() {
+  private boolean jj_3R_38() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_12()) {
+    if (jj_3R_47()) {
+    jj_scanpos = xsp;
+    if (jj_3R_48()) {
     jj_scanpos = xsp;
-    if (jj_3R_13()) {
+    if (jj_3R_49()) {
+    jj_scanpos = xsp;
+    if (jj_3R_50()) {
+    jj_scanpos = xsp;
+    if (jj_3R_51()) {
+    jj_scanpos = xsp;
+    if (jj_3R_52()) {
     jj_scanpos = xsp;
-    if (jj_3R_14()) {
+    if (jj_3R_53()) {
     jj_scanpos = xsp;
-    if (jj_3R_15()) return true;
+    if (jj_3R_54()) return true;
+    }
+    }
+    }
+    }
     }
     }
     }
     return false;
   }
 
-  private boolean jj_3R_45() {
-    if (jj_scan_token(28)) return true;
-    if (jj_3R_30()) return true;
+  private boolean jj_3R_9() {
+    if (jj_3R_10()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_26()) { jj_scanpos = xsp; break; }
+    }
     return false;
   }
 
-  private boolean jj_3R_38() {
-    if (jj_scan_token(FALSE)) return true;
+  private boolean jj_3R_39() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_55()) {
+    jj_scanpos = xsp;
+    if (jj_3R_56()) return true;
+    }
     return false;
   }
 
-  private boolean jj_3_3() {
+  private boolean jj_3R_10() {
+    if (jj_3R_11()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_31()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3_12() {
+    if (jj_scan_token(33)) return true;
+    if (jj_3R_14()) return true;
+    if (jj_scan_token(35)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_30() {
+    if (jj_3R_39()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_29() {
+    if (jj_3R_38()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_28() {
+    if (jj_scan_token(IS)) return true;
     if (jj_scan_token(NOT)) return true;
-    if (jj_scan_token(BETWEEN)) return true;
-    if (jj_3R_42()) return true;
-    if (jj_scan_token(AND)) return true;
-    if (jj_3R_42()) return true;
+    if (jj_scan_token(NULL)) return true;
     return false;
   }
 
-  private boolean jj_3R_44() {
-    if (jj_scan_token(27)) return true;
-    if (jj_3R_30()) return true;
+  private boolean jj_3_11() {
+    if (jj_scan_token(NOT)) return true;
+    if (jj_3R_12()) return true;
     return false;
   }
 
-  private boolean jj_3R_31() {
+  private boolean jj_3R_25() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_44()) {
+    if (jj_3R_29()) {
     jj_scanpos = xsp;
-    if (jj_3R_45()) {
+    if (jj_3R_30()) {
     jj_scanpos = xsp;
-    if (jj_3_1()) {
-    jj_scanpos = xsp;
-    if (jj_3R_46()) return true;
-    }
+    if (jj_3_12()) return true;
     }
     }
     return false;
   }
 
-  private boolean jj_3R_54() {
-    if (jj_scan_token(BETWEEN)) return true;
-    if (jj_3R_42()) return true;
-    if (jj_scan_token(AND)) return true;
+  private boolean jj_3R_46() {
+    if (jj_scan_token(34)) return true;
     if (jj_3R_42()) return true;
     return false;
   }
 
-  private boolean jj_3R_37() {
-    if (jj_scan_token(TRUE)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_58() {
+  private boolean jj_3R_44() {
     if (jj_scan_token(ESCAPE)) return true;
-    if (jj_3R_47()) return true;
+    if (jj_3R_42()) return true;
     return false;
   }
 
-  private boolean jj_3R_18() {
-    if (jj_scan_token(40)) return true;
-    if (jj_3R_10()) return true;
+  private boolean jj_3_2() {
+    if (jj_scan_token(IS)) return true;
+    if (jj_scan_token(NULL)) return true;
     return false;
   }
 
-  private boolean jj_3R_36() {
-    if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+  private boolean jj_3R_20() {
+    if (jj_3R_25()) return true;
     return false;
   }
 
-  private boolean jj_3R_26() {
-    if (jj_3R_30()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_31()) { jj_scanpos = xsp; break; }
-    }
+  private boolean jj_3R_42() {
+    if (jj_scan_token(STRING_LITERAL)) return true;
     return false;
   }
 
-  private boolean jj_3_2() {
+  private boolean jj_3_10() {
     if (jj_scan_token(NOT)) return true;
-    if (jj_scan_token(LIKE)) return true;
-    if (jj_3R_47()) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_59()) jj_scanpos = xsp;
+    if (jj_3R_13()) return true;
     return false;
   }
 
-  private boolean jj_3R_53() {
-    if (jj_scan_token(LIKE)) return true;
-    if (jj_3R_47()) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_58()) jj_scanpos = xsp;
+  private boolean jj_3R_27() {
+    if (jj_scan_token(28)) return true;
+    if (jj_3R_9()) return true;
     return false;
   }
 
-  private boolean jj_3R_17() {
-    if (jj_scan_token(39)) return true;
-    if (jj_3R_10()) return true;
+  private boolean jj_3R_19() {
+    if (jj_scan_token(NOT)) return true;
+    if (jj_3R_12()) return true;
     return false;
   }
 
-  private boolean jj_3R_35() {
-    if (jj_scan_token(OCTAL_LITERAL)) return true;
+  private boolean jj_3_6() {
+    if (jj_scan_token(NOT)) return true;
+    if (jj_scan_token(IN)) return true;
+    if (jj_scan_token(33)) return true;
+    if (jj_3R_42()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_46()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(35)) return true;
     return false;
   }
 
-  private boolean jj_3R_16() {
-    if (jj_scan_token(38)) return true;
-    if (jj_3R_10()) return true;
+  private boolean jj_3_9() {
+    if (jj_scan_token(36)) return true;
+    if (jj_3R_12()) return true;
     return false;
   }
 
-  private boolean jj_3R_11() {
+  private boolean jj_3_1() {
+    if (jj_scan_token(27)) return true;
+    if (jj_3R_9()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_21() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_16()) {
+    if (jj_3_1()) {
     jj_scanpos = xsp;
-    if (jj_3R_17()) {
+    if (jj_3R_27()) {
+    jj_scanpos = xsp;
+    if (jj_3_2()) {
     jj_scanpos = xsp;
-    if (jj_3R_18()) return true;
+    if (jj_3R_28()) return true;
+    }
     }
     }
     return false;
   }
 
-  private boolean jj_3R_27() {
-    if (jj_scan_token(AND)) return true;
-    if (jj_3R_26()) return true;
+  private boolean jj_3R_45() {
+    if (jj_scan_token(34)) return true;
+    if (jj_3R_42()) return true;
     return false;
   }
 
-  private boolean jj_3R_34() {
-    if (jj_scan_token(HEX_LITERAL)) return true;
+  private boolean jj_3R_18() {
+    if (jj_scan_token(NOT)) return true;
+    if (jj_3R_13()) return true;
     return false;
   }
 
-  private boolean jj_3R_9() {
-    if (jj_3R_10()) return true;
+  private boolean jj_3R_43() {
+    if (jj_scan_token(ESCAPE)) return true;
+    if (jj_3R_42()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_17() {
+    if (jj_scan_token(37)) return true;
+    if (jj_3R_12()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_13() {
+    if (jj_3R_9()) return true;
     Token xsp;
     while (true) {
       xsp = jj_scanpos;
-      if (jj_3R_11()) { jj_scanpos = xsp; break; }
+      if (jj_3R_21()) { jj_scanpos = xsp; break; }
     }
     return false;
   }
 
-  private boolean jj_3R_33() {
-    if (jj_scan_token(DECIMAL_LITERAL)) return true;
+  private boolean jj_3R_16() {
+    if (jj_scan_token(36)) return true;
+    if (jj_3R_12()) return true;
     return false;
   }
 
-  private boolean jj_3R_57() {
-    if (jj_scan_token(37)) return true;
-    if (jj_3R_9()) return true;
+  private boolean jj_3R_54() {
+    if (jj_scan_token(NULL)) return true;
     return false;
   }
 
-  private boolean jj_3R_21() {
-    if (jj_3R_26()) return true;
+  private boolean jj_3R_37() {
+    if (jj_scan_token(IN)) return true;
+    if (jj_scan_token(33)) return true;
+    if (jj_3R_42()) return true;
     Token xsp;
     while (true) {
       xsp = jj_scanpos;
-      if (jj_3R_27()) { jj_scanpos = xsp; break; }
+      if (jj_3R_45()) { jj_scanpos = xsp; break; }
     }
+    if (jj_scan_token(35)) return true;
     return false;
   }
 
-  private boolean jj_3_5() {
+  private boolean jj_3R_12() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_scan_token(36)) {
+    if (jj_3R_16()) {
     jj_scanpos = xsp;
-    if (jj_scan_token(37)) return true;
+    if (jj_3R_17()) {
+    jj_scanpos = xsp;
+    if (jj_3R_18()) {
+    jj_scanpos = xsp;
+    if (jj_3R_19()) {
+    jj_scanpos = xsp;
+    if (jj_3R_20()) return true;
+    }
+    }
+    }
     }
-    if (jj_3R_9()) return true;
     return false;
   }
 
-  private boolean jj_3R_52() {
-    if (jj_scan_token(32)) return true;
-    if (jj_3R_42()) return true;
+  private boolean jj_3R_53() {
+    if (jj_scan_token(FALSE)) return true;
     return false;
   }
 
-  private boolean jj_3R_41() {
-    if (jj_scan_token(QUOTED_ID)) return true;
+  private boolean jj_3_5() {
+    if (jj_scan_token(NOT)) return true;
+    if (jj_scan_token(BETWEEN)) return true;
+    if (jj_3R_10()) return true;
+    if (jj_scan_token(AND)) return true;
+    if (jj_3R_10()) return true;
     return false;
   }
 
-  private boolean jj_3R_56() {
-    if (jj_scan_token(36)) return true;
-    if (jj_3R_9()) return true;
+  private boolean jj_3R_58() {
+    if (jj_scan_token(AND)) return true;
+    if (jj_3R_13()) return true;
     return false;
   }
 
-  private boolean jj_3R_32() {
-    if (jj_3R_47()) return true;
+  private boolean jj_3R_36() {
+    if (jj_scan_token(BETWEEN)) return true;
+    if (jj_3R_10()) return true;
+    if (jj_scan_token(AND)) return true;
+    if (jj_3R_10()) return true;
     return false;
   }
 
-  private boolean jj_3R_51() {
-    if (jj_scan_token(31)) return true;
-    if (jj_3R_42()) return true;
+  private boolean jj_3R_52() {
+    if (jj_scan_token(TRUE)) return true;
     return false;
   }
 
-  private boolean jj_3R_40() {
-    if (jj_scan_token(ID)) return true;
+  private boolean jj_3R_22() {
+    if (jj_3R_13()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_58()) { jj_scanpos = xsp; break; }
+    }
     return false;
   }
 
-  private boolean jj_3R_61() {
-    if (jj_scan_token(34)) return true;
-    if (jj_3R_47()) return true;
+  private boolean jj_3R_24() {
+    if (jj_scan_token(40)) return true;
+    if (jj_3R_12()) return true;
     return false;
   }
 
-  private boolean jj_3R_48() {
+  private boolean jj_3R_51() {
+    if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3_4() {
+    if (jj_scan_token(NOT)) return true;
+    if (jj_scan_token(LIKE)) return true;
+    if (jj_3R_42()) return true;
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_56()) {
-    jj_scanpos = xsp;
-    if (jj_3R_57()) return true;
-    }
+    if (jj_3R_44()) jj_scanpos = xsp;
     return false;
   }
 
-  private boolean jj_3R_22() {
-    if (jj_scan_token(OR)) return true;
-    if (jj_3R_21()) return true;
+  private boolean jj_3R_23() {
+    if (jj_scan_token(39)) return true;
+    if (jj_3R_12()) return true;
     return false;
   }
 
-  private boolean jj_3R_28() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_32()) {
-    jj_scanpos = xsp;
-    if (jj_3R_33()) {
-    jj_scanpos = xsp;
-    if (jj_3R_34()) {
-    jj_scanpos = xsp;
-    if (jj_3R_35()) {
-    jj_scanpos = xsp;
-    if (jj_3R_36()) {
-    jj_scanpos = xsp;
-    if (jj_3R_37()) {
-    jj_scanpos = xsp;
-    if (jj_3R_38()) {
-    jj_scanpos = xsp;
-    if (jj_3R_39()) return true;
-    }
-    }
-    }
-    }
-    }
-    }
-    }
+  private boolean jj_3R_57() {
+    if (jj_scan_token(OR)) return true;
+    if (jj_3R_22()) return true;
     return false;
   }
 
   private boolean jj_3R_50() {
-    if (jj_scan_token(30)) return true;
-    if (jj_3R_42()) return true;
+    if (jj_scan_token(OCTAL_LITERAL)) return true;
     return false;
   }
 
-  private boolean jj_3R_29() {
+  private boolean jj_3R_35() {
+    if (jj_scan_token(LIKE)) return true;
+    if (jj_3R_42()) return true;
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_40()) {
-    jj_scanpos = xsp;
-    if (jj_3R_41()) return true;
-    }
+    if (jj_3R_43()) jj_scanpos = xsp;
     return false;
   }
 
-  private boolean jj_3R_49() {
-    if (jj_scan_token(29)) return true;
-    if (jj_3R_42()) return true;
+  private boolean jj_3_8() {
+    if (jj_scan_token(38)) return true;
+    if (jj_3R_12()) return true;
     return false;
   }
 
-  private boolean jj_3R_43() {
+  private boolean jj_3R_15() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_49()) {
-    jj_scanpos = xsp;
-    if (jj_3R_50()) {
-    jj_scanpos = xsp;
-    if (jj_3R_51()) {
-    jj_scanpos = xsp;
-    if (jj_3R_52()) {
-    jj_scanpos = xsp;
-    if (jj_3R_53()) {
-    jj_scanpos = xsp;
-    if (jj_3_2()) {
-    jj_scanpos = xsp;
-    if (jj_3R_54()) {
-    jj_scanpos = xsp;
-    if (jj_3_3()) {
+    if (jj_3_8()) {
     jj_scanpos = xsp;
-    if (jj_3R_55()) {
+    if (jj_3R_23()) {
     jj_scanpos = xsp;
-    if (jj_3_4()) return true;
-    }
-    }
-    }
-    }
-    }
-    }
-    }
+    if (jj_3R_24()) return true;
     }
     }
     return false;
   }
 
-  private boolean jj_3R_42() {
-    if (jj_3R_9()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_48()) { jj_scanpos = xsp; break; }
-    }
+  private boolean jj_3R_34() {
+    if (jj_scan_token(32)) return true;
+    if (jj_3R_10()) return true;
     return false;
   }
 
-  private boolean jj_3R_19() {
-    if (jj_3R_21()) return true;
+  private boolean jj_3R_14() {
+    if (jj_3R_22()) return true;
     Token xsp;
     while (true) {
       xsp = jj_scanpos;
-      if (jj_3R_22()) { jj_scanpos = xsp; break; }
+      if (jj_3R_57()) { jj_scanpos = xsp; break; }
     }
     return false;
   }
 
-  private boolean jj_3R_25() {
-    if (jj_scan_token(33)) return true;
-    if (jj_3R_19()) return true;
-    if (jj_scan_token(35)) return true;
+  private boolean jj_3R_49() {
+    if (jj_scan_token(HEX_LITERAL)) return true;
     return false;
   }
 
-  private boolean jj_3R_24() {
-    if (jj_3R_29()) return true;
+  private boolean jj_3R_11() {
+    if (jj_3R_12()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_15()) { jj_scanpos = xsp; break; }
+    }
     return false;
   }
 
-  private boolean jj_3R_23() {
-    if (jj_3R_28()) return true;
+  private boolean jj_3R_33() {
+    if (jj_scan_token(31)) return true;
+    if (jj_3R_10()) return true;
     return false;
   }
 
-  private boolean jj_3R_60() {
-    if (jj_scan_token(34)) return true;
-    if (jj_3R_47()) return true;
+  private boolean jj_3R_41() {
+    if (jj_scan_token(37)) return true;
+    if (jj_3R_11()) return true;
     return false;
   }
 
-  private boolean jj_3R_20() {
+  private boolean jj_3_7() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_23()) {
-    jj_scanpos = xsp;
-    if (jj_3R_24()) {
+    if (jj_scan_token(36)) {
     jj_scanpos = xsp;
-    if (jj_3R_25()) return true;
-    }
+    if (jj_scan_token(37)) return true;
     }
+    if (jj_3R_11()) return true;
     return false;
   }
 
-  private boolean jj_3R_30() {
-    if (jj_3R_42()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_43()) { jj_scanpos = xsp; break; }
-    }
+  private boolean jj_3R_48() {
+    if (jj_scan_token(DECIMAL_LITERAL)) return true;
     return false;
   }
 
-  private boolean jj_3_4() {
-    if (jj_scan_token(NOT)) return true;
-    if (jj_scan_token(IN)) return true;
-    if (jj_scan_token(33)) return true;
-    if (jj_3R_47()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_61()) { jj_scanpos = xsp; break; }
-    }
-    if (jj_scan_token(35)) return true;
+  private boolean jj_3R_32() {
+    if (jj_scan_token(30)) return true;
+    if (jj_3R_10()) return true;
     return false;
   }
 
-  private boolean jj_3_6() {
+  private boolean jj_3R_40() {
     if (jj_scan_token(36)) return true;
-    if (jj_3R_10()) return true;
+    if (jj_3R_11()) return true;
     return false;
   }
 
-  private boolean jj_3R_59() {
-    if (jj_scan_token(ESCAPE)) return true;
-    if (jj_3R_47()) return true;
+  private boolean jj_3R_56() {
+    if (jj_scan_token(QUOTED_ID)) return true;
     return false;
   }
 
   private boolean jj_3R_47() {
-    if (jj_scan_token(STRING_LITERAL)) return true;
+    if (jj_3R_42()) return true;
     return false;
   }
 
-  private boolean jj_3R_15() {
-    if (jj_3R_20()) return true;
+  private boolean jj_3_3() {
+    if (jj_scan_token(29)) return true;
+    if (jj_3R_10()) return true;
     return false;
   }
 
-  private boolean jj_3R_14() {
-    if (jj_scan_token(NOT)) return true;
-    if (jj_3R_19()) return true;
+  private boolean jj_3R_26() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_3()) {
+    jj_scanpos = xsp;
+    if (jj_3R_32()) {
+    jj_scanpos = xsp;
+    if (jj_3R_33()) {
+    jj_scanpos = xsp;
+    if (jj_3R_34()) {
+    jj_scanpos = xsp;
+    if (jj_3R_35()) {
+    jj_scanpos = xsp;
+    if (jj_3_4()) {
+    jj_scanpos = xsp;
+    if (jj_3R_36()) {
+    jj_scanpos = xsp;
+    if (jj_3_5()) {
+    jj_scanpos = xsp;
+    if (jj_3R_37()) {
+    jj_scanpos = xsp;
+    if (jj_3_6()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_55() {
+    if (jj_scan_token(ID)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_31() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_40()) {
+    jj_scanpos = xsp;
+    if (jj_3R_41()) return true;
+    }
     return false;
   }
 
@@ -1169,7 +1238,7 @@ public class SelectorParser<E> implements 
SelectorParserConstants {
     throw generateParseException();
   }
 
-  static private final class LookaheadSuccess extends Error { }
+  static private final class LookaheadSuccess extends java.lang.Error { }
   final private LookaheadSuccess jj_ls = new LookaheadSuccess();
   private boolean jj_scan_token(int kind) {
     if (jj_scanpos == jj_lastpos) {
diff --git 
a/broker-core/src/test/java/org/apache/qpid/server/filter/JMSSelectorFilterSyntaxTest.java
 
b/broker-core/src/test/java/org/apache/qpid/server/filter/JMSSelectorFilterSyntaxTest.java
index 629b048a94..26545f5d81 100644
--- 
a/broker-core/src/test/java/org/apache/qpid/server/filter/JMSSelectorFilterSyntaxTest.java
+++ 
b/broker-core/src/test/java/org/apache/qpid/server/filter/JMSSelectorFilterSyntaxTest.java
@@ -25,36 +25,77 @@ import static org.mockito.Mockito.when;
 
 import org.junit.jupiter.api.Test;
 
-public class JMSSelectorFilterSyntaxTest
+class JMSSelectorFilterSyntaxTest
 {
     @Test
-    public void equality() throws Exception
+    void equality() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("color")).thenReturn("red");
+        when(message.getHeader("size")).thenReturn("small");
         when(message.getHeader("price")).thenReturn(100);
 
         assertTrue(new JMSSelectorFilter("color = 'red'").matches(message));
+        assertTrue(new JMSSelectorFilter("size = 'small'").matches(message));
         assertTrue(new JMSSelectorFilter("price = 100").matches(message));
         assertFalse(new JMSSelectorFilter("color = 'blue'").matches(message));
+        assertFalse(new JMSSelectorFilter("size = 'big'").matches(message));
         assertFalse(new JMSSelectorFilter("price = 200").matches(message));
     }
 
     @Test
-    public void inequality() throws Exception
+    void notEquality() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("color")).thenReturn("red");
+        when(message.getHeader("size")).thenReturn("small");
+        when(message.getHeader("price")).thenReturn(100);
+
+        assertFalse(new JMSSelectorFilter("not color = 
'red'").matches(message));
+        assertFalse(new JMSSelectorFilter("not size = 
'small'").matches(message));
+        assertFalse(new JMSSelectorFilter("not price = 100").matches(message));
+        assertTrue(new JMSSelectorFilter("not color = 
'blue'").matches(message));
+        assertTrue(new JMSSelectorFilter("not size = 'big'").matches(message));
+        assertTrue(new JMSSelectorFilter("not price = 200").matches(message));
+
+        assertFalse(new JMSSelectorFilter("not (color = 'red') and not (price 
= 100) and not (size = 'small')").matches(message));
+        assertFalse(new JMSSelectorFilter("not color = 'red' and not price = 
100 and not size = 'small'").matches(message));
+        assertTrue(new JMSSelectorFilter("not (color = 'blue') and not (price 
= 200) and not (size = 'big')").matches(message));
+        assertTrue(new JMSSelectorFilter("not color = 'blue' and not price = 
200 and not size = 'big'").matches(message));
+    }
+
+    @Test
+    void inequality() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("color")).thenReturn("red");
+        when(message.getHeader("size")).thenReturn("small");
         when(message.getHeader("price")).thenReturn(100);
 
         assertTrue(new JMSSelectorFilter("color <> 'blue'").matches(message));
+        assertTrue(new JMSSelectorFilter("size <> 'big'").matches(message));
         assertTrue(new JMSSelectorFilter("price <> 200").matches(message));
         assertFalse(new JMSSelectorFilter("color <> 'red'").matches(message));
+        assertFalse(new JMSSelectorFilter("size <> 'small'").matches(message));
         assertFalse(new JMSSelectorFilter("price <> 100").matches(message));
     }
 
     @Test
-    public void greaterThan() throws Exception
+    void notInequality() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("color")).thenReturn("red");
+        when(message.getHeader("size")).thenReturn("small");
+        when(message.getHeader("price")).thenReturn(100);
+
+        assertTrue(new JMSSelectorFilter("not (color <> 'red') and not (price 
<> 100) and not (size <> 'small')").matches(message));
+        assertTrue(new JMSSelectorFilter("not color <> 'red' and not price <> 
100 and not size <> 'small'").matches(message));
+        assertFalse(new JMSSelectorFilter("not (color <> 'blue') and not 
(price <> 200) and not (size <> 'big')").matches(message));
+        assertFalse(new JMSSelectorFilter("not color <> 'blue' and not price 
<> 200 and not size <> 'big'").matches(message));
+    }
+
+    @Test
+    void greaterThan() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("price")).thenReturn(100);
@@ -64,7 +105,17 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void greaterThanOrEquals() throws Exception
+    void notGreaterThan() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("price")).thenReturn(100);
+
+        assertFalse(new JMSSelectorFilter("not price > 10").matches(message));
+        assertTrue(new JMSSelectorFilter("not price > 100").matches(message));
+    }
+
+    @Test
+    void greaterThanOrEquals() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("price")).thenReturn(100);
@@ -75,7 +126,18 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void lessThan() throws Exception
+    void notGreaterThanOrEquals() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("price")).thenReturn(100);
+
+        assertFalse(new JMSSelectorFilter("not price >= 10").matches(message));
+        assertFalse(new JMSSelectorFilter("not price >= 
100").matches(message));
+        assertTrue(new JMSSelectorFilter("not price >= 200").matches(message));
+    }
+
+    @Test
+    void lessThan() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("price")).thenReturn(100);
@@ -85,7 +147,17 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void lessThanOrEquals() throws Exception
+    void notLessThan() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("price")).thenReturn(100);
+
+        assertFalse(new JMSSelectorFilter("not price < 110").matches(message));
+        assertTrue(new JMSSelectorFilter("not price < 100").matches(message));
+    }
+
+    @Test
+    void lessThanOrEquals() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("price")).thenReturn(100);
@@ -96,7 +168,18 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void and() throws Exception
+    void notLessThanOrEquals() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("price")).thenReturn(100);
+
+        assertFalse(new JMSSelectorFilter("not price <= 
110").matches(message));
+        assertFalse(new JMSSelectorFilter("not price <= 
100").matches(message));
+        assertTrue(new JMSSelectorFilter("not price <= 10").matches(message));
+    }
+
+    @Test
+    void and() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("color")).thenReturn("red");
@@ -109,7 +192,73 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void or() throws Exception
+    void multipleAnd() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("color")).thenReturn("red");
+        when(message.getHeader("price")).thenReturn(100);
+        when(message.getHeader("size")).thenReturn("large");
+        when(message.getHeader("height")).thenReturn(10);
+        when(message.getHeader("width")).thenReturn(5);
+        when(message.getHeader("depth")).thenReturn(2);
+        when(message.getHeader("length")).thenReturn(8);
+
+        assertTrue(new JMSSelectorFilter("color = 'red' and price = 100 and 
size = 'large' and height = 10 and width = 5 and depth = 2 and length = 
8").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'blue' and price = 100 and 
size = 'large' and height = 10 and width = 5 and depth = 2 and length = 
8").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and price = 200 and 
size = 'large' and height = 10 and width = 5 and depth = 2 and length = 
8").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and 
size = 'small' and height = 10 and width = 5 and depth = 2 and length = 
8").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and 
size = 'large' and height = 11 and width = 5 and depth = 2 and length = 
8").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and 
size = 'large' and height = 10 and width = 4 and depth = 2 and length = 
8").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and 
size = 'large' and height = 10 and width = 5 and depth = 3 and length = 
8").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and 
size = 'large' and height = 10 and width = 5 and depth = 2 and length = 
9").matches(message));
+
+        assertFalse(new JMSSelectorFilter("color = 'red' and not price = 
100").matches(message));
+        assertFalse(new JMSSelectorFilter("not color = 'red' and price = 
100").matches(message));
+        assertFalse(new JMSSelectorFilter("not color = 'red' and not price = 
100").matches(message));
+        assertFalse(new JMSSelectorFilter("not (color = 'red' and price = 
100)").matches(message));
+        assertTrue(new JMSSelectorFilter("not color <> 'red' and not price <> 
100").matches(message));
+
+        assertTrue(new JMSSelectorFilter("color = 'red' and price = 100 and 
size = 'large'").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and 
not size = 'large'").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and not price = 100 
and size = 'large'").matches(message));
+        assertFalse(new JMSSelectorFilter("not color = 'red' and price = 100 
and size = 'large'").matches(message));
+        assertFalse(new JMSSelectorFilter("not color = 'red' and not price = 
100 and size = 'large'").matches(message));
+        assertFalse(new JMSSelectorFilter("not color = 'red' and not price = 
100 and not size = 'large'").matches(message));
+        assertFalse(new JMSSelectorFilter("not color = 'red' and price = 100 
and not size = 'large'").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and not price = 100 
and not size = 'large'").matches(message));
+
+        assertTrue(new JMSSelectorFilter("not color <> 'red' and not price <> 
100 and not size <> 'large'").matches(message));
+    }
+
+    @Test
+    public void chainedNot() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("color")).thenReturn("red");
+        when(message.getHeader("price")).thenReturn(100);
+        when(message.getHeader("size")).thenReturn("large");
+
+        assertFalse(new JMSSelectorFilter("not(true)").matches(message));
+        assertTrue(new JMSSelectorFilter("not not(true)").matches(message));
+        assertFalse(new JMSSelectorFilter("not not 
not(true)").matches(message));
+        assertTrue(new JMSSelectorFilter("not not not 
not(true)").matches(message));
+
+        assertFalse(new JMSSelectorFilter("true and not (false) and not 
(true)").matches(message));
+        assertFalse(new JMSSelectorFilter("true and (not false) and (not 
true)").matches(message));
+        assertFalse(new JMSSelectorFilter("color = 'red' and not (price = 200) 
and not (size = 'large')").matches(message));
+        assertTrue(new JMSSelectorFilter("color = 'red' and not (price = 200) 
and not (size = 'small')").matches(message));
+
+        when(message.getHeader("entry")).thenReturn("bbb");
+        when(message.getHeader("fruit")).thenReturn("apple");
+
+        assertTrue(new JMSSelectorFilter("not (((true and true) or (false or 
true)) and (not (price not between 90 and 110) and not (not (fruit in ('apple', 
'banana', 'cherry')) or (entry NOT LIKE '%aaa%'))))").matches(message));
+
+        when(message.getHeader("entry")).thenReturn("aaa");
+        assertFalse(new JMSSelectorFilter("not (((true and true) or (false or 
true)) and (not (price not between 90 and 110) and not (not (fruit in ('apple', 
'banana', 'cherry')) or (entry NOT LIKE '%aaa%'))))").matches(message));
+    }
+
+    @Test
+    void or() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("color")).thenReturn("red");
@@ -122,7 +271,29 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void in() throws Exception
+    void multipleOr() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("color")).thenReturn("red");
+        when(message.getHeader("price")).thenReturn(100);
+        when(message.getHeader("size")).thenReturn("large");
+        when(message.getHeader("height")).thenReturn(10);
+        when(message.getHeader("width")).thenReturn(5);
+        when(message.getHeader("depth")).thenReturn(2);
+        when(message.getHeader("length")).thenReturn(8);
+
+        assertFalse(new JMSSelectorFilter("color = 'blue' or price = 200 or 
size = 'small' or height = 11 or width = 4 or depth = 1 or length = 
9").matches(message));
+        assertTrue(new JMSSelectorFilter("color = 'red' or price = 200 or size 
= 'small' or height = 11 or width = 4 or depth = 1 or length = 
9").matches(message));
+        assertTrue(new JMSSelectorFilter("color = 'blue' or price = 100 or 
size = 'small' or height = 11 or width = 4 or depth = 1 or length = 
9").matches(message));
+        assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or 
size = 'large' or height = 11 or width = 4 or depth = 1 or length = 
9").matches(message));
+        assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or 
size = 'small' or height = 10 or width = 4 or depth = 1 or length = 
9").matches(message));
+        assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or 
size = 'small' or height = 11 or width = 5 or depth = 1 or length = 
9").matches(message));
+        assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or 
size = 'small' or height = 11 or width = 4 or depth = 2 or length = 
9").matches(message));
+        assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or 
size = 'small' or height = 11 or width = 4 or depth = 1 or length = 
8").matches(message));
+    }
+
+    @Test
+    void in() throws Exception
     {
         final Filterable message = mock(Filterable.class);
 
@@ -140,7 +311,7 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void notIn() throws Exception
+    void notIn() throws Exception
     {
         final Filterable message = mock(Filterable.class);
 
@@ -153,20 +324,23 @@ public class JMSSelectorFilterSyntaxTest
         assertFalse(new JMSSelectorFilter("fruit not in ('apple', 'banana', 
'cherry')").matches(message));
         assertFalse(new JMSSelectorFilter("not (fruit in ('apple', 'banana', 
'cherry'))").matches(message));
         assertFalse(new JMSSelectorFilter("not fruit in ('apple', 'banana', 
'cherry')").matches(message));
+        assertTrue(new JMSSelectorFilter("not fruit not in ('apple', 'banana', 
'cherry')").matches(message));
 
         when(message.getHeader("fruit")).thenReturn("cherry");
         assertFalse(new JMSSelectorFilter("fruit not in ('apple', 'banana', 
'cherry')").matches(message));
         assertFalse(new JMSSelectorFilter("not (fruit in ('apple', 'banana', 
'cherry'))").matches(message));
         assertFalse(new JMSSelectorFilter("not fruit in ('apple', 'banana', 
'cherry')").matches(message));
+        assertTrue(new JMSSelectorFilter("not fruit not in ('apple', 'banana', 
'cherry')").matches(message));
 
         when(message.getHeader("fruit")).thenReturn("mango");
         assertTrue(new JMSSelectorFilter("fruit not in ('apple', 'banana', 
'cherry')").matches(message));
         assertTrue(new JMSSelectorFilter("not (fruit in ('apple', 'banana', 
'cherry'))").matches(message));
         assertTrue(new JMSSelectorFilter("not fruit in ('apple', 'banana', 
'cherry')").matches(message));
+        assertFalse(new JMSSelectorFilter("not fruit not in ('apple', 
'banana', 'cherry')").matches(message));
     }
 
     @Test
-    public void between() throws Exception
+    void between() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("price")).thenReturn(100);
@@ -178,7 +352,7 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void notBetween() throws Exception
+    void notBetween() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("price")).thenReturn(100);
@@ -187,11 +361,13 @@ public class JMSSelectorFilterSyntaxTest
         assertFalse(new JMSSelectorFilter("price not between 100 and 
110").matches(message));
         assertFalse(new JMSSelectorFilter("price not between 90 and 
100").matches(message));
         assertTrue(new JMSSelectorFilter("price not between 110 and 
120").matches(message));
+        assertFalse(new JMSSelectorFilter("not price not between 110 and 
120").matches(message));
 
         assertFalse(new JMSSelectorFilter("not (price between 90 and 
110)").matches(message));
         assertFalse(new JMSSelectorFilter("not (price between 100 and 
110)").matches(message));
         assertFalse(new JMSSelectorFilter("not (price between 90 and 
100)").matches(message));
         assertTrue(new JMSSelectorFilter("not (price between 110 and 
120)").matches(message));
+        assertFalse(new JMSSelectorFilter("not (price not between 110 and 
120)").matches(message));
 
         assertFalse(new JMSSelectorFilter("not price between 90 and 
110").matches(message));
         assertFalse(new JMSSelectorFilter("not price between 100 and 
110").matches(message));
@@ -200,7 +376,7 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void like() throws Exception
+    void like() throws Exception
     {
         final Filterable message = mock(Filterable.class);
 
@@ -212,7 +388,7 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void notLike() throws Exception
+    void notLike() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("entry")).thenReturn("bbb");
@@ -230,10 +406,12 @@ public class JMSSelectorFilterSyntaxTest
 
         assertFalse(new JMSSelectorFilter("NOT (entry LIKE 
'%aaa%')").matches(message));
         assertFalse(new JMSSelectorFilter("NOT entry LIKE 
'%aaa%'").matches(message));
+        assertTrue(new JMSSelectorFilter("NOT (entry NOT LIKE 
'%aaa%')").matches(message));
+        assertTrue(new JMSSelectorFilter("NOT entry NOT LIKE 
'%aaa%'").matches(message));
     }
 
     @Test
-    public void isNull() throws Exception
+    void isNull() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("entry")).thenReturn("aaa");
@@ -243,7 +421,7 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void isNotNull() throws Exception
+    void isNotNull() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("entry")).thenReturn("aaa");
@@ -251,13 +429,16 @@ public class JMSSelectorFilterSyntaxTest
         assertTrue(new JMSSelectorFilter("entry is not 
null").matches(message));
         assertTrue(new JMSSelectorFilter("not (entry is 
null)").matches(message));
         assertTrue(new JMSSelectorFilter("not entry is 
null").matches(message));
+        assertFalse(new JMSSelectorFilter("not entry is not 
null").matches(message));
+
         assertFalse(new JMSSelectorFilter("another_entry is not 
null").matches(message));
         assertFalse(new JMSSelectorFilter("not (another_entry is 
null)").matches(message));
         assertFalse(new JMSSelectorFilter("not another_entry is 
null").matches(message));
+        assertTrue(new JMSSelectorFilter("not another_entry is not 
null").matches(message));
     }
 
     @Test
-    public void arithmetic() throws Exception
+    void arithmetic() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("size")).thenReturn(10);
@@ -276,7 +457,37 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void arithmeticOperatorsPrecedence() throws Exception
+    void notArithmetic() throws Exception
+    {
+        final Filterable message = mock(Filterable.class);
+        when(message.getHeader("size")).thenReturn(10);
+        when(message.getHeader("price")).thenReturn(100);
+
+        assertTrue(new JMSSelectorFilter("not (size + price = 
111)").matches(message));
+        assertTrue(new JMSSelectorFilter("not (price - size = 
91)").matches(message));
+        assertTrue(new JMSSelectorFilter("not (price / size = 
11)").matches(message));
+        assertTrue(new JMSSelectorFilter("not (price * size = 
1001)").matches(message));
+
+        assertTrue(new JMSSelectorFilter("not size + price = 
111").matches(message));
+        assertTrue(new JMSSelectorFilter("not price - size = 
91").matches(message));
+        assertTrue(new JMSSelectorFilter("not price / size = 
11").matches(message));
+        assertTrue(new JMSSelectorFilter("not price * size = 
1001").matches(message));
+
+        assertTrue(new JMSSelectorFilter("not (size / 4 = 
3.5)").matches(message));
+        assertTrue(new JMSSelectorFilter("not (size / 4.0 = 
3.5)").matches(message));
+
+        assertTrue(new JMSSelectorFilter("not size / 4 = 
3.5").matches(message));
+        assertTrue(new JMSSelectorFilter("not size / 4.0 = 
3.5").matches(message));
+
+        assertTrue(new JMSSelectorFilter("not (size * 2 = 
21.0)").matches(message));
+        assertTrue(new JMSSelectorFilter("not (size * 2.0 = 
21.0)").matches(message));
+
+        assertTrue(new JMSSelectorFilter("not size * 2 = 
21.0").matches(message));
+        assertTrue(new JMSSelectorFilter("not size * 2.0 = 
21.0").matches(message));
+    }
+
+    @Test
+    void arithmeticOperatorsPrecedence() throws Exception
     {
         final Filterable message = mock(Filterable.class);
         when(message.getHeader("size")).thenReturn(10);
@@ -290,13 +501,23 @@ public class JMSSelectorFilterSyntaxTest
     }
 
     @Test
-    public void logicOperatorsPrecedence() throws Exception
+    void logicOperatorsPrecedence() throws Exception
     {
         final Filterable message = mock(Filterable.class);
 
         when(message.getHeader("a")).thenReturn(1);
         when(message.getHeader("b")).thenReturn(2);
         when(message.getHeader("c")).thenReturn(3);
+
+        assertTrue(new JMSSelectorFilter("True or True and 
False").matches(message));
+        assertTrue(new JMSSelectorFilter("False and True or 
True").matches(message));
+
+        assertFalse(new JMSSelectorFilter("(True or True) and 
False").matches(message));
+        assertTrue(new JMSSelectorFilter("True or (True and 
False)").matches(message));
+
+        assertFalse(new JMSSelectorFilter("False and (True or 
True)").matches(message));
+        assertTrue(new JMSSelectorFilter("(False and True) or 
True").matches(message));
+
         assertTrue(new JMSSelectorFilter("a = 1 and b = 2 or c = 
3").matches(message));
         assertFalse(new JMSSelectorFilter("not a = 1 and b = 
2").matches(message));
         assertTrue(new JMSSelectorFilter("a = 1 and (b = 2 or c = 
3)").matches(message));
@@ -309,11 +530,28 @@ public class JMSSelectorFilterSyntaxTest
         when(message.getHeader("a")).thenReturn(1);
         when(message.getHeader("b")).thenReturn(2);
         when(message.getHeader("c")).thenReturn(4);
+
         assertTrue(new JMSSelectorFilter("a = 1 and b = 2 or c = 
3").matches(message));
 
         when(message.getHeader("a")).thenReturn(1);
         when(message.getHeader("b")).thenReturn(1);
         when(message.getHeader("c")).thenReturn(3);
+
         assertTrue(new JMSSelectorFilter("a = 1 and b = 2 or c = 
3").matches(message));
+
+        when(message.getHeader("a")).thenReturn(1);
+        when(message.getHeader("b")).thenReturn(2);
+        when(message.getHeader("c")).thenReturn(3);
+
+        assertTrue(new JMSSelectorFilter("a = 1 and not b = 2 or c = 
3").matches(message));
+        assertTrue(new JMSSelectorFilter("(a = 1 and not b = 2) or c = 
3").matches(message));
+        assertFalse(new JMSSelectorFilter("a = 1 and not (b = 2 or c = 
3)").matches(message));
+        assertTrue(new JMSSelectorFilter("not (a = 1 and not b = 2) or c = 
3").matches(message));
+
+        assertTrue(new JMSSelectorFilter("a = 1 or not b = 2 and c = 
3").matches(message));
+        assertTrue(new JMSSelectorFilter("(a = 1 or not b = 2) and c = 
3").matches(message));
+        assertTrue(new JMSSelectorFilter("a = 1 or (not b = 2 and c = 
3)").matches(message));
+        assertTrue(new JMSSelectorFilter("a = 1 or not (b = 2 and c = 
3)").matches(message));
+        assertFalse(new JMSSelectorFilter("not (a = 1 or not b = 2) and c = 
3").matches(message));
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to