Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 3866)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 3867)
@@ -32,9 +32,9 @@
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData;
 import org.openstreetmap.josm.gui.NavigatableComponent;
-import org.openstreetmap.josm.gui.mappaint.ElemStyle;
 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle;
 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.Symbol;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Utils;
 
 public class MapPainter {
@@ -309,5 +309,5 @@
             g.setPaint(texture);
             if (color.getAlpha() != 255) {
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ElemStyle.color_int2float(color.getAlpha())));
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, Utils.color_int2float(color.getAlpha())));
             }
             g.fill(polygon);
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java	(revision 3866)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java	(revision 3867)
@@ -71,4 +71,7 @@
                 if (args.length == 0)
                     return 0f;
+                if (args.length == 1) { // unary minus
+                    return -args[0];
+                }
                 float res = args[0];
                 for (int i=1; i<args.length; ++i) {
@@ -167,4 +170,33 @@
                 for (boolean b : bs) {
                     if (b)
+                        return true;
+                }
+                return false;
+            }
+
+            public boolean greater_equal(float a, float b) {
+                return a >= b;
+            }
+
+            public boolean less_equal(float a, float b) {
+                return a <= b;
+            }
+
+            public boolean greater(float a, float b) {
+                return a > b;
+            }
+
+            public boolean less(float a, float b) {
+                return a < b;
+            }
+
+            public boolean equal(Object a, Object b) {
+                // make sure the casts are done in a meaningful way, so
+                // the 2 objects really can be considered equal
+                for (Class klass : new Class[] {
+                        Float.class, Boolean.class, Color.class, float[].class, String.class }) {
+                    Object a2 = Cascade.convertTo(a, klass);
+                    Object b2 = Cascade.convertTo(a, klass);
+                    if (a2 != null && b2 != null && a2.equals(b2))
                         return true;
                 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java	(revision 3866)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java	(revision 3867)
@@ -186,5 +186,5 @@
       }
       r = rule();
-                 sheet.rules.add(r);
+                 if (r != null) { sheet.rules.add(r); }
       w();
     }
@@ -196,22 +196,27 @@
     Selector sel;
     List<Instruction> decl;
-    sel = selector();
-                     selectors.add(sel);
-    w();
-    label_4:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case COMMA:
-        ;
-        break;
-      default:
-        jj_la1[7] = jj_gen;
-        break label_4;
-      }
-      jj_consume_token(COMMA);
-      w();
+    try {
       sel = selector();
                          selectors.add(sel);
       w();
+      label_4:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case COMMA:
+          ;
+          break;
+        default:
+          jj_la1[7] = jj_gen;
+          break label_4;
+        }
+        jj_consume_token(COMMA);
+        w();
+        sel = selector();
+                             selectors.add(sel);
+        w();
+      }
+    } catch (ParseException ex) {
+        error_skipto(RBRACE);
+        {if (true) return null;}
     }
     decl = declaration();
@@ -272,4 +277,5 @@
     }
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SLASH:
     case DCOLON:
       sub = subpart();
@@ -338,4 +344,5 @@
       case HEXCOLOR:
       case LPAR:
+      case EXCLAMATION:
       case PLUS:
       case MINUS:
@@ -414,5 +421,16 @@
   final public String subpart() throws ParseException {
     Token t;
-    jj_consume_token(DCOLON);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SLASH:
+      jj_consume_token(SLASH);
+      break;
+    case DCOLON:
+      jj_consume_token(DCOLON);
+      break;
+    default:
+      jj_la1[20] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
     case IDENT:
@@ -423,5 +441,5 @@
       break;
     default:
-      jj_la1[20] = jj_gen;
+      jj_la1[21] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
@@ -442,5 +460,5 @@
       break;
     default:
-      jj_la1[21] = jj_gen;
+      jj_la1[22] = jj_gen;
       ;
     }
@@ -455,5 +473,5 @@
           break;
         default:
-          jj_la1[22] = jj_gen;
+          jj_la1[23] = jj_gen;
           break label_6;
         }
@@ -466,5 +484,5 @@
           break;
         default:
-          jj_la1[23] = jj_gen;
+          jj_la1[24] = jj_gen;
           ;
         }
@@ -499,4 +517,5 @@
       case HEXCOLOR:
       case LPAR:
+      case EXCLAMATION:
       case PLUS:
       case MINUS:
@@ -504,5 +523,5 @@
         break;
       default:
-        jj_la1[24] = jj_gen;
+        jj_la1[25] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
@@ -520,132 +539,215 @@
     Expression e;
     String op = null;
-    e = primary();
-                  args.add(e);
-    w();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case STAR:
-    case SLASH:
-    case PIPE:
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case EXCLAMATION:
+      jj_consume_token(EXCLAMATION);
+                          op = "not";
+      w();
+      e = primary();
+                                                          args.add(e);
+      w();
+      break;
+    case MINUS:
+      jj_consume_token(MINUS);
+                    op = "minus";
+      w();
+      e = primary();
+                                                      args.add(e);
+      w();
+      break;
+    case IDENT:
+    case UINT:
+    case UFLOAT:
+    case STRING:
+    case HEXCOLOR:
+    case LPAR:
     case PLUS:
-    case MINUS:
-    case AMPERSAND:
-    case QUESTION:
+      e = primary();
+                          args.add(e);
+      w();
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case STAR:
+      case SLASH:
+      case GREATER_EQUAL:
+      case LESS_EQUAL:
+      case GREATER:
+      case LESS:
+      case EQUAL:
+      case PIPE:
       case PLUS:
-        label_7:
-        while (true) {
-          jj_consume_token(PLUS);
-                       op = "plus";
+      case MINUS:
+      case AMPERSAND:
+      case QUESTION:
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case PLUS:
+          label_7:
+          while (true) {
+            jj_consume_token(PLUS);
+                               op = "plus";
+            w();
+            e = primary();
+                                                                args.add(e);
+            w();
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case PLUS:
+              ;
+              break;
+            default:
+              jj_la1[26] = jj_gen;
+              break label_7;
+            }
+          }
+          break;
+        case STAR:
+          label_8:
+          while (true) {
+            jj_consume_token(STAR);
+                               op = "times";
+            w();
+            e = primary();
+                                                                 args.add(e);
+            w();
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case STAR:
+              ;
+              break;
+            default:
+              jj_la1[27] = jj_gen;
+              break label_8;
+            }
+          }
+          break;
+        case MINUS:
+          label_9:
+          while (true) {
+            jj_consume_token(MINUS);
+                                op = "minus";
+            w();
+            e = primary();
+                                                                  args.add(e);
+            w();
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case MINUS:
+              ;
+              break;
+            default:
+              jj_la1[28] = jj_gen;
+              break label_9;
+            }
+          }
+          break;
+        case SLASH:
+          label_10:
+          while (true) {
+            jj_consume_token(SLASH);
+                                op = "divided_by";
+            w();
+            e = primary();
+                                                                       args.add(e);
+            w();
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case SLASH:
+              ;
+              break;
+            default:
+              jj_la1[29] = jj_gen;
+              break label_10;
+            }
+          }
+          break;
+        case GREATER_EQUAL:
+          jj_consume_token(GREATER_EQUAL);
+                                        op = "greater_equal";
           w();
           e = primary();
-                                                        args.add(e);
-          w();
+                                                                                  args.add(e);
+          w();
+          break;
+        case LESS_EQUAL:
+          jj_consume_token(LESS_EQUAL);
+                                     op = "less_equal";
+          w();
+          e = primary();
+                                                                            args.add(e);
+          w();
+          break;
+        case GREATER:
+          jj_consume_token(GREATER);
+                                  op = "greater";
+          w();
+          e = primary();
+                                                                      args.add(e);
+          w();
+          break;
+        case EQUAL:
+          jj_consume_token(EQUAL);
           switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case PLUS:
-            ;
+          case EQUAL:
+            jj_consume_token(EQUAL);
             break;
           default:
-            jj_la1[25] = jj_gen;
-            break label_7;
+            jj_la1[30] = jj_gen;
+            ;
           }
+                                             op = "equal";
+          w();
+          e = primary();
+                                                                               args.add(e);
+          w();
+          break;
+        case LESS:
+          jj_consume_token(LESS);
+                               op = "less";
+          w();
+          e = primary();
+                                                                args.add(e);
+          w();
+          break;
+        case AMPERSAND:
+          jj_consume_token(AMPERSAND);
+          jj_consume_token(AMPERSAND);
+                                                op = "and";
+          w();
+          e = primary();
+                                                                                args.add(e);
+          w();
+          break;
+        case PIPE:
+          jj_consume_token(PIPE);
+          jj_consume_token(PIPE);
+                                      op = "or";
+          w();
+          e = primary();
+                                                                     args.add(e);
+          w();
+          break;
+        case QUESTION:
+          jj_consume_token(QUESTION);
+                                   op = "cond";
+          w();
+          e = primary();
+                                                                    args.add(e);
+          w();
+          jj_consume_token(COLON);
+          w();
+          e = primary();
+                                                                                                                 args.add(e);
+          w();
+          break;
+        default:
+          jj_la1[31] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
         }
         break;
-      case STAR:
-        label_8:
-        while (true) {
-          jj_consume_token(STAR);
-                       op = "times";
-          w();
-          e = primary();
-                                                         args.add(e);
-          w();
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case STAR:
-            ;
-            break;
-          default:
-            jj_la1[26] = jj_gen;
-            break label_8;
-          }
-        }
-        break;
-      case MINUS:
-        label_9:
-        while (true) {
-          jj_consume_token(MINUS);
-                        op = "minus";
-          w();
-          e = primary();
-                                                          args.add(e);
-          w();
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case MINUS:
-            ;
-            break;
-          default:
-            jj_la1[27] = jj_gen;
-            break label_9;
-          }
-        }
-        break;
-      case SLASH:
-        label_10:
-        while (true) {
-          jj_consume_token(SLASH);
-                        op = "divided_by";
-          w();
-          e = primary();
-                                                               args.add(e);
-          w();
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case SLASH:
-            ;
-            break;
-          default:
-            jj_la1[28] = jj_gen;
-            break label_10;
-          }
-        }
-        break;
-      case AMPERSAND:
-        jj_consume_token(AMPERSAND);
-        jj_consume_token(AMPERSAND);
-                                        op = "and";
-        w();
-        e = primary();
-                                                                        args.add(e);
-        w();
-        break;
-      case PIPE:
-        jj_consume_token(PIPE);
-        jj_consume_token(PIPE);
-                              op = "or";
-        w();
-        e = primary();
-                                                             args.add(e);
-        w();
-        break;
-      case QUESTION:
-        jj_consume_token(QUESTION);
-                           op = "cond";
-        w();
-        e = primary();
-                                                            args.add(e);
-        w();
-        jj_consume_token(COLON);
-        w();
-        e = primary();
-                                                                                                         args.add(e);
-        w();
-        break;
       default:
-        jj_la1[29] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-      break;
-    default:
-      jj_la1[30] = jj_gen;
-      ;
+        jj_la1[32] = jj_gen;
+        ;
+      }
+      break;
+    default:
+      jj_la1[33] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
     }
         if (op == null)
@@ -671,5 +773,4 @@
       case HEXCOLOR:
       case PLUS:
-      case MINUS:
         lit = literal();
                         {if (true) return new LiteralExpression(lit);}
@@ -683,5 +784,5 @@
         break;
       default:
-        jj_la1[31] = jj_gen;
+        jj_la1[34] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
@@ -708,4 +809,5 @@
     case HEXCOLOR:
     case LPAR:
+    case EXCLAMATION:
     case PLUS:
     case MINUS:
@@ -719,5 +821,5 @@
           break;
         default:
-          jj_la1[32] = jj_gen;
+          jj_la1[35] = jj_gen;
           break label_11;
         }
@@ -729,5 +831,5 @@
       break;
     default:
-      jj_la1[33] = jj_gen;
+      jj_la1[36] = jj_gen;
       ;
     }
@@ -751,9 +853,4 @@
       f = ufloat();
                                 {if (true) return new Instruction.RelativeFloat(f);}
-      break;
-    case MINUS:
-      jj_consume_token(MINUS);
-      f = ufloat();
-                                 {if (true) return -f;}
       break;
     case UINT:
@@ -773,5 +870,5 @@
       break;
     default:
-      jj_la1[34] = jj_gen;
+      jj_la1[37] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
@@ -789,5 +886,7 @@
     do {
         t = getNextToken();
-    } while (t.kind != kind);
+    } while (t.kind != kind && t.kind != EOF);
+    if (t.kind == EOF)
+        throw new ParseException("Reached end of file while parsing");
   }
 
@@ -820,19 +919,4 @@
   }
 
-  private boolean jj_3R_20() {
-    if (jj_scan_token(COMMA)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_16() {
-    if (jj_scan_token(EXCLAMATION)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_25() {
-    if (jj_scan_token(STRING)) return true;
-    return false;
-  }
-
   private boolean jj_3R_12() {
     Token xsp;
@@ -840,4 +924,19 @@
     if (jj_3R_16()) jj_scanpos = xsp;
     if (jj_3R_17()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_20() {
+    if (jj_scan_token(COMMA)) return true;
+    return false;
+  }
+
+  private boolean jj_3_4() {
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_25() {
+    if (jj_scan_token(STRING)) return true;
     return false;
   }
@@ -859,8 +958,6 @@
   }
 
-  private boolean jj_3R_15() {
-    if (jj_scan_token(IDENT)) return true;
-    if (jj_3R_21()) return true;
-    if (jj_scan_token(LPAR)) return true;
+  private boolean jj_3_2() {
+    if (jj_3R_13()) return true;
     return false;
   }
@@ -881,6 +978,7 @@
   }
 
-  private boolean jj_3_2() {
-    if (jj_3R_13()) return true;
+  private boolean jj_3_1() {
+    if (jj_3R_12()) return true;
+    if (jj_scan_token(RSQUARE)) return true;
     return false;
   }
@@ -896,10 +994,4 @@
   }
 
-  private boolean jj_3_1() {
-    if (jj_3R_12()) return true;
-    if (jj_scan_token(RSQUARE)) return true;
-    return false;
-  }
-
   private boolean jj_3R_21() {
     Token xsp;
@@ -916,11 +1008,25 @@
   }
 
-  private boolean jj_3_4() {
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
   private boolean jj_3R_18() {
     if (jj_scan_token(EXCLAMATION_EQUAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_15() {
+    if (jj_scan_token(IDENT)) return true;
+    if (jj_3R_21()) return true;
+    if (jj_scan_token(LPAR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_13() {
+    if (jj_3R_17()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_18()) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(20)) return true;
+    }
+    if (jj_3R_17()) return true;
     return false;
   }
@@ -941,13 +1047,6 @@
   }
 
-  private boolean jj_3R_13() {
-    if (jj_3R_17()) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_18()) {
-    jj_scanpos = xsp;
-    if (jj_scan_token(16)) return true;
-    }
-    if (jj_3R_17()) return true;
+  private boolean jj_3R_16() {
+    if (jj_scan_token(EXCLAMATION)) return true;
     return false;
   }
@@ -964,5 +1063,5 @@
   private int jj_la;
   private int jj_gen;
-  final private int[] jj_la1 = new int[35];
+  final private int[] jj_la1 = new int[38];
   static private int[] jj_la1_0;
   static private int[] jj_la1_1;
@@ -972,8 +1071,8 @@
    }
    private static void jj_la1_init_0() {
-      jj_la1_0 = new int[] {0xc,0x12,0x80,0x20000080,0x20000080,0x400000,0x102,0x400000,0x102,0x1000000,0x81000,0x81000,0x100000,0x4,0x4000000,0x4000004,0x600405e,0x20000,0x50000,0x20000,0x102,0x800,0x200000,0x800,0x600405e,0x2000000,0x100,0x4000000,0x200,0x1e800300,0x1e800300,0x600405e,0x400000,0x600405e,0x600005e,};
+      jj_la1_0 = new int[] {0xc,0x12,0x80,0x80,0x80,0x4000000,0x102,0x4000000,0x102,0x10000000,0x801000,0x801000,0x1000200,0x4,0x40000000,0x40000004,0x6020405e,0x200000,0x500000,0x200000,0x1000200,0x102,0x800,0x2000000,0x800,0x6020405e,0x20000000,0x100,0x40000000,0x200,0x100000,0xe81f0300,0xe81f0300,0x6020405e,0x2000405e,0x4000000,0x6020405e,0x2000005e,};
    }
    private static void jj_la1_init_1() {
-      jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+      jj_la1_1 = new int[] {0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0,0x0,};
    }
   final private JJCalls[] jj_2_rtns = new JJCalls[4];
@@ -992,5 +1091,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 35; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 38; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1007,5 +1106,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 35; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 38; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1018,5 +1117,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 35; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 38; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1029,5 +1128,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 35; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 38; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1039,5 +1138,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 35; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 38; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1049,5 +1148,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 35; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 38; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1161,10 +1260,10 @@
   public ParseException generateParseException() {
     jj_expentries.clear();
-    boolean[] la1tokens = new boolean[33];
+    boolean[] la1tokens = new boolean[37];
     if (jj_kind >= 0) {
       la1tokens[jj_kind] = true;
       jj_kind = -1;
     }
-    for (int i = 0; i < 35; i++) {
+    for (int i = 0; i < 38; i++) {
       if (jj_la1[i] == jj_gen) {
         for (int j = 0; j < 32; j++) {
@@ -1178,5 +1277,5 @@
       }
     }
-    for (int i = 0; i < 33; i++) {
+    for (int i = 0; i < 37; i++) {
       if (la1tokens[i]) {
         jj_expentry = new int[1];
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj	(revision 3866)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj	(revision 3867)
@@ -48,4 +48,8 @@
 |   < LPAR: "(" >
 |   < RPAR: ")" >
+|   < GREATER_EQUAL: ">=" >
+|   < LESS_EQUAL: "<=" >
+|   < GREATER: ">" >
+|   < LESS: "<" >
 |   < EQUAL: "=" >
 |   < EXCLAMATION: "!" >
@@ -188,5 +192,5 @@
     { this.sheet = sheet; }
     w()
-    ( r=rule() { sheet.rules.add(r); } w() )*
+    ( r=rule() { if (r != null) { sheet.rules.add(r); } } w() )*
     <EOF>
 }
@@ -199,9 +203,14 @@
 }
 {
-    sel=selector() { selectors.add(sel); } w()
-    (
-        <COMMA> w()
+    try {
         sel=selector() { selectors.add(sel); } w()
-    )*
+        (
+            <COMMA> w()
+            sel=selector() { selectors.add(sel); } w()
+        )*
+    } catch (ParseException ex) {
+        error_skipto(RBRACE);
+        return null;
+    }
     decl=declaration()
     { return new MapCSSRule(selectors, decl); }
@@ -298,5 +307,5 @@
 }
 {
-    <DCOLON>
+    ( <SLASH> | <DCOLON> )
     ( t=<IDENT> | t=<STAR> )
     { return t.image; }
@@ -354,20 +363,39 @@
 }
 {
-    e=primary() { args.add(e); } w()
     (
-            ( <PLUS> { op = "plus"; } w() e=primary() { args.add(e); } w() )+
-        |
-            ( <STAR> { op = "times"; } w() e=primary() { args.add(e); } w() )+
-        |
-            ( <MINUS> { op = "minus"; } w() e=primary() { args.add(e); } w() )+
-        |
-            ( <SLASH> { op = "divided_by"; } w() e=primary() { args.add(e); } w() )+
-        |
-            ( <AMPERSAND> <AMPERSAND> { op = "and"; } w() e=primary() { args.add(e); } w() )
-        |
-            ( <PIPE> <PIPE> { op = "or"; } w() e=primary() { args.add(e); } w() )
-        |
-            ( <QUESTION> { op = "cond"; } w() e=primary() { args.add(e); } w() <COLON> w() e=primary() { args.add(e); } w() )
-    )?
+        ( <EXCLAMATION> { op = "not"; } w() e=primary() { args.add(e); } w() )
+    |
+        ( <MINUS> { op = "minus"; } w() e=primary() { args.add(e); } w() )
+    |
+    
+        (
+            e=primary() { args.add(e); } w()
+            (
+                    ( <PLUS> { op = "plus"; } w() e=primary() { args.add(e); } w() )+
+                |
+                    ( <STAR> { op = "times"; } w() e=primary() { args.add(e); } w() )+
+                |
+                    ( <MINUS> { op = "minus"; } w() e=primary() { args.add(e); } w() )+
+                |
+                    ( <SLASH> { op = "divided_by"; } w() e=primary() { args.add(e); } w() )+
+                |
+                    ( <GREATER_EQUAL> { op = "greater_equal"; } w() e=primary() { args.add(e); } w() )
+                |
+                    ( <LESS_EQUAL> { op = "less_equal"; } w() e=primary() { args.add(e); } w() )
+                |
+                    ( <GREATER> { op = "greater"; } w() e=primary() { args.add(e); } w() )
+                |
+                    ( <EQUAL> ( <EQUAL> )? { op = "equal"; } w() e=primary() { args.add(e); } w() )
+                |
+                    ( <LESS> { op = "less"; } w() e=primary() { args.add(e); } w() )
+                |
+                    ( <AMPERSAND> <AMPERSAND> { op = "and"; } w() e=primary() { args.add(e); } w() )
+                |
+                    ( <PIPE> <PIPE> { op = "or"; } w() e=primary() { args.add(e); } w() )
+                |
+                    ( <QUESTION> { op = "cond"; } w() e=primary() { args.add(e); } w() <COLON> w() e=primary() { args.add(e); } w() )
+            )?
+        )
+    )
     {
         if (op == null)
@@ -420,6 +448,4 @@
     |
         ( <PLUS> f=ufloat() ) { return new Instruction.RelativeFloat(f); }
-    |
-        ( <MINUS> f=ufloat() ) { return -f; }
     |
         f=ufloat() { return f; }
@@ -447,5 +473,7 @@
     do {
         t = getNextToken();
-    } while (t.kind != kind);
-}
-
+    } while (t.kind != kind && t.kind != EOF);
+    if (t.kind == EOF)
+        throw new ParseException("Reached end of file while parsing");
+}
+
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserConstants.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserConstants.java	(revision 3866)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserConstants.java	(revision 3867)
@@ -42,35 +42,43 @@
   int RPAR = 15;
   /** RegularExpression Id. */
-  int EQUAL = 16;
+  int GREATER_EQUAL = 16;
   /** RegularExpression Id. */
-  int EXCLAMATION = 17;
+  int LESS_EQUAL = 17;
   /** RegularExpression Id. */
-  int EXCLAMATION_EQUAL = 18;
+  int GREATER = 18;
   /** RegularExpression Id. */
-  int COLON = 19;
+  int LESS = 19;
   /** RegularExpression Id. */
-  int DCOLON = 20;
+  int EQUAL = 20;
   /** RegularExpression Id. */
-  int SEMICOLON = 21;
+  int EXCLAMATION = 21;
   /** RegularExpression Id. */
-  int COMMA = 22;
+  int EXCLAMATION_EQUAL = 22;
   /** RegularExpression Id. */
-  int PIPE = 23;
+  int COLON = 23;
   /** RegularExpression Id. */
-  int PIPE_Z = 24;
+  int DCOLON = 24;
   /** RegularExpression Id. */
-  int PLUS = 25;
+  int SEMICOLON = 25;
   /** RegularExpression Id. */
-  int MINUS = 26;
+  int COMMA = 26;
   /** RegularExpression Id. */
-  int AMPERSAND = 27;
+  int PIPE = 27;
   /** RegularExpression Id. */
-  int QUESTION = 28;
+  int PIPE_Z = 28;
   /** RegularExpression Id. */
-  int COMMENT_START = 29;
+  int PLUS = 29;
   /** RegularExpression Id. */
-  int UNEXPECTED_CHAR = 30;
+  int MINUS = 30;
   /** RegularExpression Id. */
-  int COMMENT_END = 31;
+  int AMPERSAND = 31;
+  /** RegularExpression Id. */
+  int QUESTION = 32;
+  /** RegularExpression Id. */
+  int COMMENT_START = 33;
+  /** RegularExpression Id. */
+  int UNEXPECTED_CHAR = 34;
+  /** RegularExpression Id. */
+  int COMMENT_END = 35;
 
   /** Lexical state. */
@@ -97,4 +105,8 @@
     "\"(\"",
     "\")\"",
+    "\">=\"",
+    "\"<=\"",
+    "\">\"",
+    "\"<\"",
     "\"=\"",
     "\"!\"",
@@ -113,5 +125,5 @@
     "<UNEXPECTED_CHAR>",
     "\"*/\"",
-    "<token of kind 32>",
+    "<token of kind 36>",
   };
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserTokenManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserTokenManager.java	(revision 3866)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserTokenManager.java	(revision 3867)
@@ -45,8 +45,8 @@
    {
       case 33:
-         jjmatchedKind = 17;
-         return jjMoveStringLiteralDfa1_0(0x40000L);
+         jjmatchedKind = 21;
+         return jjMoveStringLiteralDfa1_0(0x400000L);
       case 38:
-         return jjStopAtPos(0, 27);
+         return jjStopAtPos(0, 31);
       case 40:
          return jjStopAtPos(0, 14);
@@ -56,21 +56,27 @@
          return jjStopAtPos(0, 8);
       case 43:
-         return jjStopAtPos(0, 25);
+         return jjStopAtPos(0, 29);
       case 44:
-         return jjStopAtPos(0, 22);
+         return jjStopAtPos(0, 26);
       case 45:
-         return jjStopAtPos(0, 26);
+         return jjStopAtPos(0, 30);
       case 47:
          jjmatchedKind = 9;
-         return jjMoveStringLiteralDfa1_0(0x20000000L);
+         return jjMoveStringLiteralDfa1_0(0x200000000L);
       case 58:
+         jjmatchedKind = 23;
+         return jjMoveStringLiteralDfa1_0(0x1000000L);
+      case 59:
+         return jjStopAtPos(0, 25);
+      case 60:
          jjmatchedKind = 19;
-         return jjMoveStringLiteralDfa1_0(0x100000L);
-      case 59:
-         return jjStopAtPos(0, 21);
+         return jjMoveStringLiteralDfa1_0(0x20000L);
       case 61:
-         return jjStopAtPos(0, 16);
+         return jjStopAtPos(0, 20);
+      case 62:
+         jjmatchedKind = 18;
+         return jjMoveStringLiteralDfa1_0(0x10000L);
       case 63:
-         return jjStopAtPos(0, 28);
+         return jjStopAtPos(0, 32);
       case 91:
          return jjStopAtPos(0, 12);
@@ -80,6 +86,6 @@
          return jjStopAtPos(0, 10);
       case 124:
-         jjmatchedKind = 23;
-         return jjMoveStringLiteralDfa1_0(0x1000000L);
+         jjmatchedKind = 27;
+         return jjMoveStringLiteralDfa1_0(0x10000000L);
       case 125:
          return jjStopAtPos(0, 11);
@@ -98,18 +104,22 @@
    {
       case 42:
-         if ((active0 & 0x20000000L) != 0L)
-            return jjStopAtPos(1, 29);
+         if ((active0 & 0x200000000L) != 0L)
+            return jjStopAtPos(1, 33);
          break;
       case 58:
-         if ((active0 & 0x100000L) != 0L)
-            return jjStopAtPos(1, 20);
+         if ((active0 & 0x1000000L) != 0L)
+            return jjStopAtPos(1, 24);
          break;
       case 61:
-         if ((active0 & 0x40000L) != 0L)
-            return jjStopAtPos(1, 18);
+         if ((active0 & 0x10000L) != 0L)
+            return jjStopAtPos(1, 16);
+         else if ((active0 & 0x20000L) != 0L)
+            return jjStopAtPos(1, 17);
+         else if ((active0 & 0x400000L) != 0L)
+            return jjStopAtPos(1, 22);
          break;
       case 122:
-         if ((active0 & 0x1000000L) != 0L)
-            return jjStopAtPos(1, 24);
+         if ((active0 & 0x10000000L) != 0L)
+            return jjStopAtPos(1, 28);
          break;
       default :
@@ -351,5 +361,5 @@
    {
       case 42:
-         return jjMoveStringLiteralDfa1_1(0x80000000L);
+         return jjMoveStringLiteralDfa1_1(0x800000000L);
       default :
          return 1;
@@ -365,6 +375,6 @@
    {
       case 47:
-         if ((active0 & 0x80000000L) != 0L)
-            return jjStopAtPos(1, 31);
+         if ((active0 & 0x800000000L) != 0L)
+            return jjStopAtPos(1, 35);
          break;
       default :
@@ -392,6 +402,7 @@
 public static final String[] jjstrLiteralImages = {
 "", null, null, null, null, null, null, null, "\52", "\57", "\173", "\175", 
-"\133", "\135", "\50", "\51", "\75", "\41", "\41\75", "\72", "\72\72", "\73", "\54", 
-"\174", "\174\172", "\53", "\55", "\46", "\77", "\57\52", null, "\52\57", null, };
+"\133", "\135", "\50", "\51", "\76\75", "\74\75", "\76", "\74", "\75", "\41", 
+"\41\75", "\72", "\72\72", "\73", "\54", "\174", "\174\172", "\53", "\55", "\46", "\77", 
+"\57\52", null, "\52\57", null, };
 
 /** Lexer state names. */
@@ -404,11 +415,11 @@
 public static final int[] jjnewLexState = {
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-   -1, -1, -1, -1, 1, -1, 0, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 0, -1, 
 };
 static final long[] jjtoToken = {
-   0xffffffdfL, 
+   0xfffffffdfL, 
 };
 static final long[] jjtoSkip = {
-   0x100000000L, 
+   0x1000000000L, 
 };
 protected SimpleCharStream input_stream;
@@ -518,7 +529,7 @@
        jjmatchedPos = 0;
        curPos = jjMoveStringLiteralDfa0_0();
-       if (jjmatchedPos == 0 && jjmatchedKind > 30)
+       if (jjmatchedPos == 0 && jjmatchedKind > 34)
        {
-          jjmatchedKind = 30;
+          jjmatchedKind = 34;
        }
        break;
@@ -527,7 +538,7 @@
        jjmatchedPos = 0;
        curPos = jjMoveStringLiteralDfa0_1();
-       if (jjmatchedPos == 0 && jjmatchedKind > 32)
+       if (jjmatchedPos == 0 && jjmatchedKind > 36)
        {
-          jjmatchedKind = 32;
+          jjmatchedKind = 36;
        }
        break;
