Index: trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 3893)
@@ -10,4 +10,5 @@
 import java.util.Collection;
 import java.util.List;
+import java.util.Map.Entry;
 
 import javax.swing.event.ChangeEvent;
@@ -31,4 +32,5 @@
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
 import org.openstreetmap.josm.gui.NavigatableComponent;
+import org.openstreetmap.josm.gui.mappaint.Cascade;
 import org.openstreetmap.josm.gui.mappaint.ElemStyle;
 import org.openstreetmap.josm.gui.mappaint.ElemStyles;
@@ -288,6 +290,6 @@
                     s.apply(mc, osm, scale, null, false);
                     txtMappaint.append("\nRange:"+mc.range);
-                    for (String key : mc.keySet()) {
-                        txtMappaint.append("\n "+key+": \n"+mc.get(key));
+                    for (Entry<String, Cascade> e : mc.getLayers()) {
+                        txtMappaint.append("\n "+e.getKey()+": \n"+e.getValue());
                     }
                 } else {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java	(revision 3893)
@@ -16,21 +16,7 @@
 public class Cascade implements Cloneable {
     
-    public static final Cascade EMPTY_CASCADE = new Cascade(false);
+    public static final Cascade EMPTY_CASCADE = new Cascade();
 
     protected Map<String, Object> prop = new HashMap<String, Object>();
-
-    /**
-     * constructor
-     * @param isModifier Everything that is not on the default layer is assumed to
-     *                   be a modifier. Can be overridden in style definition.
-     */
-    public Cascade(boolean isModifier) {
-        if (isModifier) {
-            put("modifier", true);
-        }
-    }
-
-    private Cascade() {
-    }
 
     public <T> T get(String key, T def, Class<T> klass) {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 3893)
@@ -219,5 +219,5 @@
         }
 
-        for (Entry<String, Cascade> e : mc.entrySet()) {
+        for (Entry<String, Cascade> e : mc.getLayers()) {
             if ("*".equals(e.getKey()))
                 continue;
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java	(revision 3893)
@@ -3,7 +3,4 @@
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.gui.mappaint.Cascade;
-import org.openstreetmap.josm.gui.mappaint.MultiCascade;
-import org.openstreetmap.josm.gui.mappaint.StyleSource;
 
 public class Environment {
@@ -21,6 +18,3 @@
     }
 
-    public Cascade getCascade() {
-        return mc.getCascade(layer);
-    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 3893)
@@ -19,9 +19,8 @@
 
     public static LineElemStyle createSimpleLineStyle(Color color) {
-        Cascade c = new Cascade(false);
+        MultiCascade mc = new MultiCascade();
+        Cascade c = mc.getOrCreateCascade("default");
         c.put("width", -1f);
         c.put("color", color != null ? color : PaintColors.UNTAGGED.get());
-        MultiCascade mc = new MultiCascade();
-        mc.put("default", c);
         return createLine(new Environment(null, mc, "default", null));
     }
@@ -60,5 +59,5 @@
 
     private static LineElemStyle createImpl(Environment env, boolean casing) {
-        Cascade c = env.getCascade();
+        Cascade c = env.mc.getCascade(env.layer);
         Cascade c_def = env.mc.getCascade("default");
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 3893)
@@ -37,5 +37,4 @@
 
     private static ElemStyles styles = new ElemStyles();
-    private static Collection<String> iconDirs;
 
     public static ElemStyles getStyles()
@@ -62,7 +61,36 @@
     public static ImageIcon getIcon(IconReference ref, boolean sanitize)
     {
-        String styleName = ref.source.getPrefName();
+        String namespace = ref.source.getPrefName();
+        ImageIcon i = ImageProvider.getIfAvailable(getIconSourceDirs(ref.source), "mappaint."+namespace, null, ref.iconName, ref.source.zipIcons, sanitize);
+        if(i == null)
+        {
+            System.out.println("Mappaint style \""+namespace+"\" icon \"" + ref.iconName + "\" not found.");
+            return null;
+        }
+        return i;
+    }
+
+    /**
+     * No icon with the given name was found, show a dummy icon instead
+     * @return the icon misc/no_icon.png, in descending priority:
+     *   - relative to source file
+     *   - from user icon paths
+     *   - josm's default icon
+     *  can be null if the defaults are turned off by user
+     */
+    public static ImageIcon getNoIcon_Icon(StyleSource source, boolean sanitize) {
+        return ImageProvider.getIfAvailable(getIconSourceDirs(source), "mappaint."+source.getPrefName(), null, "misc/no_icon.png", source.zipIcons, sanitize);
+    }
+
+    private static List<String> getIconSourceDirs(StyleSource source) {
         List<String> dirs = new LinkedList<String>();
-        for(String fileset : iconDirs)
+
+        String sourceDir = source.getLocalSourceDir();
+        if (sourceDir != null) {
+            dirs.add(sourceDir);
+        }
+
+        Collection<String> prefIconDirs = Main.pref.getCollection("mappaint.icon.sources");
+        for(String fileset : prefIconDirs)
         {
             String[] a;
@@ -74,32 +102,20 @@
 
             /* non-prefixed path is generic path, always take it */
-            if(a[0].length() == 0 || styleName.equals(a[0])) {
+            if(a[0].length() == 0 || source.getPrefName().equals(a[0])) {
                 dirs.add(a[1]);
             }
         }
-        String sourceDir = ref.source.getLocalSourceDir();
-        if (sourceDir != null) {
-            dirs.add(sourceDir);
-        }
-        ImageIcon i = ImageProvider.getIfAvailable(dirs, "mappaint."+styleName, null, ref.iconName, ref.source.zipIcons, sanitize);
-        if(i == null)
-        {
-            System.out.println("Mappaint style \""+styleName+"\" icon \"" + ref.iconName + "\" not found.");
-            i = ImageProvider.getIfAvailable(dirs, "mappaint."+styleName, null, "misc/no_icon.png");
-        }
-        return i;
+
+        if (Main.pref.getBoolean("mappaint.icon.enable-defaults", true)) {
+            /* don't prefix icon path, as it should be generic */
+            dirs.add("resource://images/styles/standard/");
+            dirs.add("resource://images/styles/");
+        }
+        
+        return dirs;
     }
 
     public static void readFromPreferences() {
         styles.clear();
-        iconDirs = Main.pref.getCollection("mappaint.icon.sources", Collections.<String>emptySet());
-        if(Main.pref.getBoolean("mappaint.icon.enable-defaults", true))
-        {
-            LinkedList<String> f = new LinkedList<String>(iconDirs);
-            /* don't prefix icon path, as it should be generic */
-            f.add("resource://images/styles/standard/");
-            f.add("resource://images/styles/");
-            iconDirs = f;
-        }
 
         Collection<? extends SourceEntry> sourceEntries = MapPaintPrefMigration.INSTANCE.get();
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MultiCascade.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MultiCascade.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MultiCascade.java	(revision 3893)
@@ -2,32 +2,74 @@
 package org.openstreetmap.josm.gui.mappaint;
 
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
 
 /**
- * Several cascades, e.g. one for the main Line and one for each overlay.
- * The range is (0,Inf) at first and it shrinks in the process when
+ * Several layers / cascades, e.g. one for the main Line and one for each overlay.
+ * The range is (0,Infinity) at first and it shrinks in the process when
  * StyleSources apply zoom level dependent properties.
  */
-public class MultiCascade extends HashMap<String, Cascade> {
+public class MultiCascade {
+    
+    private Map<String, Cascade> layers;
     public Range range;
 
     public MultiCascade() {
-        super();
+        layers = new HashMap<String, Cascade>();
         range = new Range();
     }
 
     /**
-     * Return the cascade for the given layer key. If it does not exist,
-     * return a new cascade, but do not keep it.
+     * Return the cascade with the given name. If it doesn't exist, create
+     * a new layer with that name and return it. The new layer will be
+     * a clone of the "*" layer, if it exists.
      */
-    public Cascade getCascade(String layer) {
+    public Cascade getOrCreateCascade(String layer) {
         if (layer == null)
             throw new IllegalArgumentException();
-        Cascade c = get(layer);
+        Cascade c = layers.get(layer);
         if (c == null) {
-            c = new Cascade(!layer.equals("default"));
+            if (layers.containsKey("*")) {
+                c = layers.get("*").clone();
+            } else {
+                c = new Cascade();
+                // Everything that is not on the default layer is assumed to
+                // be a modifier. Can be overridden in style definition.
+                if (!layer.equals("default")) {
+                    c.put("modifier", true);
+                }
+            }
+            layers.put(layer, c);
         }
         return c;
     }
 
+    /**
+     * Read-only version of getOrCreateCascade. For convenience, it returns an
+     * empty cascade for non-existing layers. However this empty (read-only) cascade
+     * is not added to this MultiCascade object.
+     */
+    public Cascade getCascade(String layer) {
+        if (layer == null) {
+            layer = "default";
+        }
+        Cascade c = layers.get(layer);
+        if (c == null) {
+            c = new Cascade();
+            if (!layer.equals("default")) {
+                c.put("modifier", true);
+            }
+        }
+        return c;
+    }
+
+    public Collection<Entry<String, Cascade>> getLayers() {
+        return layers.entrySet();
+    }
+
+    public boolean hasLayer(String layer) {
+        return layers.containsKey(layer);
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 3893)
@@ -124,5 +124,5 @@
     public static final NodeElemStyle SIMPLE_NODE_ELEMSTYLE;
     static {
-        Cascade c = new Cascade(false);
+        Cascade c = new Cascade();
         c.put("text", "auto");
         SIMPLE_NODE_ELEMSTYLE = create(c, true);
@@ -149,4 +149,7 @@
         if (iconRef != null) {
             icon = MapPaintStyles.getIcon(iconRef, false);
+            if (icon == null) {
+                icon = MapPaintStyles.getNoIcon_Icon(iconRef.source, false);
+            }
             iconAlpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.icon-image-alpha", 255))));
             Integer pAlpha = Utils.color_float2int(c.get("icon-opacity", null, float.class));
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java	(revision 3893)
@@ -9,4 +9,5 @@
 
 import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
@@ -98,13 +99,18 @@
         private String k;
         private boolean not;
+        private boolean yes;
 
-        public KeyCondition(String k, boolean not) {
+        public KeyCondition(String k, boolean not, boolean yes) {
             this.k = k;
             this.not = not;
+            this.yes = yes;
         }
 
         @Override
         public boolean applies(Environment e) {
-            return e.osm.hasKey(k) ^ not;
+            if (yes)
+                return OsmUtils.isTrue(e.osm.get(k)) ^ not;
+            else
+                return e.osm.hasKey(k) ^ not;
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java	(revision 3893)
@@ -122,5 +122,5 @@
                 Cascade c;
                 if (layer == null) {
-                    c = env.getCascade();
+                    c = env.mc.getCascade(env.layer);
                 } else {
                     c = env.mc.getCascade(layer);
@@ -136,5 +136,8 @@
                 Cascade c;
                 if (layer == null) {
-                    c = env.getCascade();
+                    // env.layer is null if expression is evaluated
+                    // in ExpressionCondition, but MultiCascade.getCascade
+                    // handles this
+                    c = env.mc.getCascade(env.layer);
                 } else {
                     c = env.mc.getCascade(layer);
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java	(revision 3893)
@@ -45,5 +45,5 @@
                 }
             }
-            env.getCascade().putOrClear(key, value);
+            env.mc.getOrCreateCascade(env.layer).putOrClear(key, value);
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 3893)
@@ -58,5 +58,5 @@
             System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
             e.printStackTrace();
-            logError(e);
+            logError(new ParseException(e.getMessage())); // allow e to be garbage collected, it links to the entire token stream
         }
     }
@@ -124,17 +124,10 @@
                     }
 
-                    Cascade c = mc.get(sub);
-                    if (c == null) {
-                        if (mc.containsKey("*")) {
-                            c = mc.get("*").clone();
-                        } else {
-                            c = new Cascade(!sub.equals("default"));
-                        }
-                        mc.put(sub, c);
-                    }
-
                     if (sub.equals("*")) {
-                        for (Entry<String, Cascade> entry : mc.entrySet()) {
+                        for (Entry<String, Cascade> entry : mc.getLayers()) {
                             env.layer = entry.getKey();
+                            if (Utils.equal(env.layer, "*")) {
+                                continue;
+                            }
                             for (Instruction i : r.declaration) {
                                 i.execute(env);
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java	(revision 3893)
@@ -393,4 +393,5 @@
   final public Condition simple_key_condition() throws ParseException {
     boolean not = false;
+    boolean yes = false;
     String key;
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -404,5 +405,14 @@
     }
     key = string_or_ident();
-      {if (true) return new Condition.KeyCondition(key, not);}
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case QUESTION:
+      jj_consume_token(QUESTION);
+                   yes = true;
+      break;
+    default:
+      jj_la1[19] = jj_gen;
+      ;
+    }
+      {if (true) return new Condition.KeyCondition(key, not, yes);}
     throw new Error("Missing return statement in function");
   }
@@ -442,5 +452,5 @@
           break;
         default:
-          jj_la1[19] = jj_gen;
+          jj_la1[20] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
@@ -472,5 +482,5 @@
         break;
       default:
-        jj_la1[20] = jj_gen;
+        jj_la1[21] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
@@ -500,5 +510,5 @@
         break;
       default:
-        jj_la1[21] = jj_gen;
+        jj_la1[22] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
@@ -508,5 +518,5 @@
       break;
     default:
-      jj_la1[22] = jj_gen;
+      jj_la1[23] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
@@ -524,5 +534,5 @@
       break;
     default:
-      jj_la1[23] = jj_gen;
+      jj_la1[24] = jj_gen;
       ;
     }
@@ -544,5 +554,5 @@
       break;
     default:
-      jj_la1[24] = jj_gen;
+      jj_la1[25] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
@@ -566,5 +576,5 @@
         break;
       default:
-        jj_la1[25] = jj_gen;
+        jj_la1[26] = jj_gen;
         break label_6;
       }
@@ -587,5 +597,5 @@
           break;
         default:
-          jj_la1[26] = jj_gen;
+          jj_la1[27] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
@@ -604,5 +614,5 @@
           break;
         default:
-          jj_la1[27] = jj_gen;
+          jj_la1[28] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
@@ -678,5 +688,5 @@
               break;
             default:
-              jj_la1[28] = jj_gen;
+              jj_la1[29] = jj_gen;
               break label_7;
             }
@@ -697,5 +707,5 @@
               break;
             default:
-              jj_la1[29] = jj_gen;
+              jj_la1[30] = jj_gen;
               break label_8;
             }
@@ -716,5 +726,5 @@
               break;
             default:
-              jj_la1[30] = jj_gen;
+              jj_la1[31] = jj_gen;
               break label_9;
             }
@@ -735,5 +745,5 @@
               break;
             default:
-              jj_la1[31] = jj_gen;
+              jj_la1[32] = jj_gen;
               break label_10;
             }
@@ -771,5 +781,5 @@
             break;
           default:
-            jj_la1[32] = jj_gen;
+            jj_la1[33] = jj_gen;
             ;
           }
@@ -820,5 +830,5 @@
           break;
         default:
-          jj_la1[33] = jj_gen;
+          jj_la1[34] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
@@ -826,10 +836,10 @@
         break;
       default:
-        jj_la1[34] = jj_gen;
+        jj_la1[35] = jj_gen;
         ;
       }
       break;
     default:
-      jj_la1[35] = jj_gen;
+      jj_la1[36] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
@@ -868,5 +878,5 @@
         break;
       default:
-        jj_la1[36] = jj_gen;
+        jj_la1[37] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
@@ -905,5 +915,5 @@
           break;
         default:
-          jj_la1[37] = jj_gen;
+          jj_la1[38] = jj_gen;
           break label_11;
         }
@@ -915,5 +925,5 @@
       break;
     default:
-      jj_la1[38] = jj_gen;
+      jj_la1[39] = jj_gen;
       ;
     }
@@ -954,5 +964,5 @@
       break;
     default:
-      jj_la1[39] = jj_gen;
+      jj_la1[40] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
@@ -962,9 +972,11 @@
 
   void error_skipto(int kind) throws ParseException {
+    if (token.kind == EOF)
+        throw new ParseException("Reached end of file while parsing");
     ParseException e = generateParseException();
     System.err.println("Skipping to the next rule, because of an error:");
     System.err.println(e);
     if (sheet != null) {
-        sheet.logError(e);
+        sheet.logError(new ParseException(e.getMessage()));
     }
     Token t;
@@ -984,4 +996,12 @@
     while (true) {
         t = getNextToken();
+        if ((t.kind == S || t.kind == STRING || t.kind == UNEXPECTED_CHAR) &&
+                t.image.contains("\n")) {
+            ParseException e = new ParseException(String.format("Warning: end of line while reading an unquoted string at line %s column %s.", t.beginLine, t.beginColumn));
+            System.err.println(e);
+            if (sheet != null) {
+                sheet.logError(e);
+            }
+        }
         if (t.kind == SEMICOLON || t.kind == EOF)
             break;
@@ -1028,27 +1048,15 @@
   }
 
-  private boolean jj_3R_17() {
-    if (jj_scan_token(IDENT)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_scan_token(LPAR)) return true;
-    if (jj_3R_15()) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_70()) jj_scanpos = xsp;
-    if (jj_scan_token(RPAR)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_29() {
-    if (jj_3R_45()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_24() {
+  private boolean jj_3R_30() {
+    if (jj_3R_46()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_25() {
     Token xsp;
     xsp = jj_scanpos;
     if (jj_scan_token(9)) {
     jj_scanpos = xsp;
-    if (jj_3R_42()) return true;
+    if (jj_3R_43()) return true;
     }
     return false;
@@ -1059,10 +1067,10 @@
     while (true) {
       xsp = jj_scanpos;
-      if (jj_3R_24()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  private boolean jj_3R_51() {
+      if (jj_3R_25()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_52() {
     if (jj_scan_token(LPAR)) return true;
     if (jj_3R_15()) return true;
@@ -1072,10 +1080,23 @@
   }
 
-  private boolean jj_3R_50() {
-    if (jj_3R_65()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_41() {
+  private boolean jj_3R_51() {
+    if (jj_3R_66()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_44() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_5()) {
+    jj_scanpos = xsp;
+    if (jj_3R_51()) {
+    jj_scanpos = xsp;
+    if (jj_3R_52()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_42() {
     Token xsp;
     xsp = jj_scanpos;
@@ -1084,22 +1105,4 @@
   }
 
-  private boolean jj_3R_49() {
-    if (jj_3R_22()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_43() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3_5()) {
-    jj_scanpos = xsp;
-    if (jj_3R_50()) {
-    jj_scanpos = xsp;
-    if (jj_3R_51()) return true;
-    }
-    }
-    return false;
-  }
-
   private boolean jj_3_5() {
     if (jj_3R_17()) return true;
@@ -1107,35 +1110,53 @@
   }
 
+  private boolean jj_3R_50() {
+    if (jj_3R_23()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_64() {
+    if (jj_scan_token(QUESTION)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
   private boolean jj_3R_63() {
-    if (jj_scan_token(QUESTION)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    if (jj_scan_token(COLON)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_62() {
     if (jj_scan_token(PIPE)) return true;
     if (jj_scan_token(PIPE)) return true;
     if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_39() {
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_40() {
     if (jj_scan_token(LESS)) return true;
     return false;
   }
 
-  private boolean jj_3R_61() {
+  private boolean jj_3R_62() {
     if (jj_scan_token(AMPERSAND)) return true;
     if (jj_scan_token(AMPERSAND)) return true;
     if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_39() {
+    if (jj_scan_token(LESS_EQUAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_61() {
+    if (jj_scan_token(LESS)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
     if (jj_3R_15()) return true;
     return false;
@@ -1143,27 +1164,9 @@
 
   private boolean jj_3R_38() {
-    if (jj_scan_token(LESS_EQUAL)) return true;
+    if (jj_scan_token(GREATER)) return true;
     return false;
   }
 
   private boolean jj_3R_60() {
-    if (jj_scan_token(LESS)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_37() {
-    if (jj_scan_token(GREATER)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_64() {
-    if (jj_scan_token(REGEX)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_59() {
     if (jj_scan_token(EQUAL)) return true;
     Token xsp;
@@ -1171,5 +1174,31 @@
     if (jj_scan_token(22)) jj_scanpos = xsp;
     if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_37() {
+    if (jj_scan_token(GREATER_EQUAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_65() {
+    if (jj_scan_token(REGEX)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_59() {
+    if (jj_scan_token(GREATER)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_58() {
+    if (jj_scan_token(LESS_EQUAL)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
     if (jj_3R_15()) return true;
     return false;
@@ -1177,25 +1206,4 @@
 
   private boolean jj_3R_36() {
-    if (jj_scan_token(GREATER_EQUAL)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_58() {
-    if (jj_scan_token(GREATER)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_57() {
-    if (jj_scan_token(LESS_EQUAL)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_35() {
     if (jj_scan_token(STAR)) return true;
     if (jj_scan_token(EQUAL)) return true;
@@ -1204,41 +1212,26 @@
   }
 
-  private boolean jj_3R_69() {
+  private boolean jj_3R_70() {
     if (jj_scan_token(SLASH)) return true;
     if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_56() {
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_57() {
     if (jj_scan_token(GREATER_EQUAL)) return true;
     if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_47() {
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_48() {
     if (jj_3R_19()) return true;
     return false;
   }
 
-  private boolean jj_3R_19() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_28()) {
-    jj_scanpos = xsp;
-    if (jj_3R_29()) return true;
-    }
-    return false;
-  }
-
-  private boolean jj_3R_28() {
-    if (jj_scan_token(IDENT)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_34() {
+  private boolean jj_3R_35() {
     if (jj_scan_token(DOLLAR)) return true;
     if (jj_scan_token(EQUAL)) return true;
@@ -1247,8 +1240,71 @@
   }
 
+  private boolean jj_3R_69() {
+    if (jj_scan_token(MINUS)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_56() {
+    Token xsp;
+    if (jj_3R_70()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_70()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_47() {
+    if (jj_scan_token(TILDE)) return true;
+    if (jj_3R_65()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_19() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_29()) {
+    jj_scanpos = xsp;
+    if (jj_3R_30()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_29() {
+    if (jj_scan_token(IDENT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_22() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_37()) {
+    jj_scanpos = xsp;
+    if (jj_3R_38()) {
+    jj_scanpos = xsp;
+    if (jj_3R_39()) {
+    jj_scanpos = xsp;
+    if (jj_3R_40()) return true;
+    }
+    }
+    }
+    if (jj_3R_41()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_34() {
+    if (jj_scan_token(CARET)) return true;
+    if (jj_scan_token(EQUAL)) return true;
+    if (jj_3R_19()) return true;
+    return false;
+  }
+
   private boolean jj_3R_68() {
-    if (jj_scan_token(MINUS)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
+    if (jj_scan_token(STAR)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
     if (jj_3R_15()) return true;
     return false;
@@ -1265,29 +1321,6 @@
   }
 
-  private boolean jj_3R_46() {
+  private boolean jj_3R_33() {
     if (jj_scan_token(TILDE)) return true;
-    if (jj_3R_64()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_21() {
-    Token xsp;
-    xsp = jj_scanpos;
-    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;
-    }
-    }
-    }
-    if (jj_3R_40()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_33() {
-    if (jj_scan_token(CARET)) return true;
     if (jj_scan_token(EQUAL)) return true;
     if (jj_3R_19()) return true;
@@ -1296,7 +1329,7 @@
 
   private boolean jj_3R_67() {
-    if (jj_scan_token(STAR)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
+    if (jj_scan_token(PLUS)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
     if (jj_3R_15()) return true;
     return false;
@@ -1313,19 +1346,4 @@
   }
 
-  private boolean jj_3R_32() {
-    if (jj_scan_token(TILDE)) return true;
-    if (jj_scan_token(EQUAL)) return true;
-    if (jj_3R_19()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_66() {
-    if (jj_scan_token(PLUS)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
   private boolean jj_3R_53() {
     Token xsp;
@@ -1338,19 +1356,7 @@
   }
 
-  private boolean jj_3R_52() {
-    Token xsp;
-    if (jj_3R_66()) return true;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_66()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  private boolean jj_3R_44() {
+  private boolean jj_3R_45() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_52()) {
-    jj_scanpos = xsp;
     if (jj_3R_53()) {
     jj_scanpos = xsp;
@@ -1373,36 +1379,38 @@
     if (jj_3R_62()) {
     jj_scanpos = xsp;
-    if (jj_3R_63()) return true;
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    return false;
-  }
-
-  private boolean jj_3R_45() {
+    if (jj_3R_63()) {
+    jj_scanpos = xsp;
+    if (jj_3R_64()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_46() {
     if (jj_scan_token(STRING)) return true;
     return false;
   }
 
+  private boolean jj_3R_32() {
+    if (jj_scan_token(EQUAL)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_47()) {
+    jj_scanpos = xsp;
+    if (jj_3R_48()) return true;
+    }
+    return false;
+  }
+
   private boolean jj_3R_31() {
-    if (jj_scan_token(EQUAL)) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_46()) {
-    jj_scanpos = xsp;
-    if (jj_3R_47()) return true;
-    }
-    return false;
-  }
-
-  private boolean jj_3R_30() {
     if (jj_scan_token(EXCLAMATION)) return true;
     if (jj_scan_token(EQUAL)) return true;
@@ -1411,16 +1419,47 @@
   }
 
-  private boolean jj_3R_48() {
+  private boolean jj_3R_49() {
     if (jj_scan_token(MINUS)) return true;
-    if (jj_3R_22()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_40() {
+    if (jj_3R_23()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_41() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_48()) {
-    jj_scanpos = xsp;
-    if (jj_3R_49()) return true;
+    if (jj_3R_49()) {
+    jj_scanpos = xsp;
+    if (jj_3R_50()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_28() {
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_45()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_21() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_31()) {
+    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_3R_36()) return true;
+    }
+    }
+    }
+    }
     }
     return false;
@@ -1428,43 +1467,20 @@
 
   private boolean jj_3R_27() {
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_44()) jj_scanpos = xsp;
-    return false;
-  }
-
-  private boolean jj_3R_20() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_30()) {
-    jj_scanpos = xsp;
-    if (jj_3R_31()) {
-    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()) return true;
-    }
-    }
-    }
-    }
-    }
+    if (jj_scan_token(MINUS)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
     return false;
   }
 
   private boolean jj_3R_26() {
-    if (jj_scan_token(MINUS)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_22() {
+    if (jj_scan_token(EXCLAMATION)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_3R_44()) return true;
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_23() {
     Token xsp;
     xsp = jj_scanpos;
@@ -1476,20 +1492,12 @@
   }
 
-  private boolean jj_3R_25() {
-    if (jj_scan_token(EXCLAMATION)) return true;
-    if (jj_3R_15()) return true;
-    if (jj_3R_43()) return true;
-    if (jj_3R_15()) return true;
-    return false;
-  }
-
   private boolean jj_3R_16() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_25()) {
-    jj_scanpos = xsp;
     if (jj_3R_26()) {
     jj_scanpos = xsp;
-    if (jj_3R_27()) return true;
+    if (jj_3R_27()) {
+    jj_scanpos = xsp;
+    if (jj_3R_28()) return true;
     }
     }
@@ -1512,18 +1520,18 @@
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_20()) {
-    jj_scanpos = xsp;
-    if (jj_3R_21()) return true;
-    }
+    if (jj_3R_21()) {
+    jj_scanpos = xsp;
+    if (jj_3R_22()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_75() {
+    if (jj_scan_token(HEXCOLOR)) return true;
     return false;
   }
 
   private boolean jj_3R_74() {
-    if (jj_scan_token(HEXCOLOR)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_73() {
-    if (jj_3R_22()) return true;
+    if (jj_3R_23()) return true;
     return false;
   }
@@ -1541,28 +1549,33 @@
   }
 
+  private boolean jj_3R_73() {
+    if (jj_scan_token(PLUS)) return true;
+    if (jj_3R_23()) return true;
+    return false;
+  }
+
   private boolean jj_3R_72() {
-    if (jj_scan_token(PLUS)) return true;
-    if (jj_3R_22()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_71() {
     if (jj_3R_19()) return true;
     return false;
   }
 
-  private boolean jj_3R_65() {
+  private boolean jj_3R_66() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_71()) {
-    jj_scanpos = xsp;
     if (jj_3R_72()) {
     jj_scanpos = xsp;
     if (jj_3R_73()) {
     jj_scanpos = xsp;
-    if (jj_3R_74()) return true;
-    }
-    }
-    }
+    if (jj_3R_74()) {
+    jj_scanpos = xsp;
+    if (jj_3R_75()) return true;
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_20() {
+    if (jj_scan_token(QUESTION)) return true;
     return false;
   }
@@ -1578,15 +1591,17 @@
     if (jj_3R_18()) jj_scanpos = xsp;
     if (jj_3R_19()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_23() {
+    xsp = jj_scanpos;
+    if (jj_3R_20()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_24() {
     if (jj_scan_token(COMMA)) return true;
-    if (jj_3R_41()) return true;
-    if (jj_3R_22()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_75() {
+    if (jj_3R_42()) return true;
+    if (jj_3R_23()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_76() {
     if (jj_scan_token(COMMA)) return true;
     if (jj_3R_15()) return true;
@@ -1595,21 +1610,21 @@
   }
 
-  private boolean jj_3R_14() {
-    if (jj_3R_22()) return true;
-    Token xsp;
-    if (jj_3R_23()) return true;
+  private boolean jj_3R_71() {
+    if (jj_3R_16()) return true;
+    Token xsp;
     while (true) {
       xsp = jj_scanpos;
-      if (jj_3R_23()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  private boolean jj_3R_70() {
-    if (jj_3R_16()) return true;
-    Token xsp;
+      if (jj_3R_76()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_14() {
+    if (jj_3R_23()) return true;
+    Token xsp;
+    if (jj_3R_24()) return true;
     while (true) {
       xsp = jj_scanpos;
-      if (jj_3R_75()) { jj_scanpos = xsp; break; }
+      if (jj_3R_24()) { jj_scanpos = xsp; break; }
     }
     return false;
@@ -1622,5 +1637,5 @@
   }
 
-  private boolean jj_3R_42() {
+  private boolean jj_3R_43() {
     if (jj_scan_token(COMMENT_START)) return true;
     if (jj_scan_token(COMMENT_END)) return true;
@@ -1631,4 +1646,16 @@
     if (jj_3R_12()) return true;
     if (jj_scan_token(RSQUARE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_17() {
+    if (jj_scan_token(IDENT)) return true;
+    if (jj_3R_15()) return true;
+    if (jj_scan_token(LPAR)) return true;
+    if (jj_3R_15()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_71()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAR)) return true;
     return false;
   }
@@ -1645,5 +1672,5 @@
   private int jj_la;
   private int jj_gen;
-  final private int[] jj_la1 = new int[40];
+  final private int[] jj_la1 = new int[41];
   static private int[] jj_la1_0;
   static private int[] jj_la1_1;
@@ -1653,8 +1680,8 @@
    }
    private static void jj_la1_init_0() {
-      jj_la1_0 = new int[] {0xc,0xc,0x12,0x200,0x200,0x200,0x10000000,0x402,0x10000000,0x402,0x40000000,0x2804000,0x2804000,0x4000000,0x4,0x0,0x4,0x8081011e,0x800000,0x1000012,0x1c00400,0x3c0000,0x1fc0400,0x800000,0x402,0x2,0x8002000,0x8002000,0x80000000,0x400,0x0,0x800,0x400000,0xa07c0c00,0xa07c0c00,0x8081011e,0x8001011e,0x10000000,0x8081011e,0x8000011e,};
+      jj_la1_0 = new int[] {0xc,0xc,0x12,0x200,0x200,0x200,0x10000000,0x402,0x10000000,0x402,0x40000000,0x2804000,0x2804000,0x4000000,0x4,0x0,0x4,0x8081011e,0x800000,0x0,0x1000012,0x1c00400,0x3c0000,0x1fc0400,0x800000,0x402,0x2,0x8002000,0x8002000,0x80000000,0x400,0x0,0x800,0x400000,0xa07c0c00,0xa07c0c00,0x8081011e,0x8001011e,0x10000000,0x8081011e,0x8000011e,};
    }
    private static void jj_la1_init_1() {
-      jj_la1_1 = new int[] {0x0,0x1,0x0,0x0,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x0,0x0,0x18,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x7,0x7,0x1,0x0,0x0,0x1,0x0,};
+      jj_la1_1 = new int[] {0x0,0x1,0x0,0x0,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x0,0x4,0x0,0x18,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x7,0x7,0x1,0x0,0x0,0x1,0x0,};
    }
   final private JJCalls[] jj_2_rtns = new JJCalls[5];
@@ -1673,5 +1700,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 41; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1688,5 +1715,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 41; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1699,5 +1726,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 41; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1710,5 +1737,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 41; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1720,5 +1747,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 41; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1730,5 +1757,5 @@
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 41; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
@@ -1847,5 +1874,5 @@
       jj_kind = -1;
     }
-    for (int i = 0; i < 40; i++) {
+    for (int i = 0; i < 41; i++) {
       if (jj_la1[i] == jj_gen) {
         for (int j = 0; j < 32; j++) {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj	(revision 3893)
@@ -290,4 +290,5 @@
 {
     boolean not = false;
+    boolean yes = false;
     String key;
 }
@@ -295,5 +296,6 @@
     ( <EXCLAMATION> { not = true; } )?
     key=string_or_ident()
-    { return new Condition.KeyCondition(key, not); }
+    ( <QUESTION> { yes = true; } )?
+    { return new Condition.KeyCondition(key, not, yes); }
 }
 
@@ -504,9 +506,11 @@
 JAVACODE
 void error_skipto(int kind) {
+    if (token.kind == EOF)
+        throw new ParseException("Reached end of file while parsing");
     ParseException e = generateParseException();
     System.err.println("Skipping to the next rule, because of an error:");
     System.err.println(e);
     if (sheet != null) {
-        sheet.logError(e);
+        sheet.logError(new ParseException(e.getMessage()));
     }
     Token t;
@@ -527,4 +531,12 @@
     while (true) {
         t = getNextToken();
+        if ((t.kind == S || t.kind == STRING || t.kind == UNEXPECTED_CHAR) &&
+                t.image.contains("\n")) {
+            ParseException e = new ParseException(String.format("Warning: end of line while reading an unquoted string at line %s column %s.", t.beginLine, t.beginColumn));
+            System.err.println(e);
+            if (sheet != null) {
+                sheet.logError(e);
+            }
+        }
         if (t.kind == SEMICOLON || t.kind == EOF)
             break;
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java	(revision 3891)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java	(revision 3893)
@@ -278,9 +278,5 @@
     @Override
     public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed) {
-        Cascade def = mc.get("default");
-        if (def == null) {
-            def = new Cascade(false);
-            mc.put("default", def);
-        }
+        Cascade def = mc.getOrCreateCascade("default");
         boolean useMinMaxScale = Main.pref.getBoolean("mappaint.zoomLevelDisplay", false);
 
@@ -319,6 +315,6 @@
                 int numOver = 0, numUnder = 0;
 
-                while (mc.containsKey(String.format("over_%d", ++numOver))) {}
-                while (mc.containsKey(String.format("under_%d", ++numUnder))) {}
+                while (mc.hasLayer(String.format("over_%d", ++numOver))) {}
+                while (mc.hasLayer(String.format("under_%d", ++numUnder))) {}
 
                 for (LinemodPrototype mod : p.linemods) {
@@ -326,18 +322,10 @@
                     if (mod.over) {
                         String layer = String.format("over_%d", numOver);
-                        c = mc.get(layer);
-                        if (c == null) {
-                            c = new Cascade(true);
-                            mc.put(layer, c);
-                        }
+                        c = mc.getOrCreateCascade(layer);
                         c.put("object-z-index", new Float(numOver));
                         ++numOver;
                     } else {
                         String layer = String.format("under_%d", numUnder);
-                        c = mc.get(layer);
-                        if (c == null) {
-                            c = new Cascade(true);
-                            mc.put(layer, c);
-                        }
+                        c = mc.getOrCreateCascade(layer);
                         c.put("object-z-index", new Float(-numUnder));
                         ++numUnder;
