Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java	(revision 3804)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java	(revision 3805)
@@ -19,5 +19,5 @@
         this.maxScale = maxScale;
         this.minScale = minScale;
-        this.rules = a.rules;
+        this.conditions = a.conditions;
         this.line = new LineElemStyle();
         this.line.color = a.color;
@@ -31,5 +31,5 @@
         this.maxScale = a.maxScale;
         this.minScale = a.minScale;
-        this.rules = a.rules;
+        this.conditions = a.conditions;
         this.line = l;
         this.code = a.code;
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java	(revision 3804)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java	(revision 3805)
@@ -8,4 +8,5 @@
 import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
 import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
+import org.openstreetmap.josm.gui.mappaint.xml.XmlCondition;
 
 abstract public class ElemStyle {
@@ -16,5 +17,5 @@
     public int priority;
     public String code;
-    Collection<Rule> rules = null;
+    Collection<XmlCondition> conditions = null;
 
     @Override
@@ -29,9 +30,9 @@
 
     public String getCode() {
-        if(code == null) {
+        if (code == null) {
             code = "";
-            if (rules != null) {
-                for(Rule r: rules) {
-                    code += r.toCode();
+            if (conditions != null) {
+                for (XmlCondition c: conditions) {
+                    code += c.toCode();
                 }
             }
@@ -41,11 +42,11 @@
     public boolean check(OsmPrimitive primitive)
     {
-        if(rules == null)
+        if(conditions == null)
             return true;
-        for(Rule r : rules)
+        for(XmlCondition c : conditions)
         {
-            String k = primitive.get(r.key);
-            String bv = OsmUtils.getNamedOsmBoolean(r.boolValue);
-            if(k == null || (r.value != null && !k.equals(r.value))
+            String k = primitive.get(c.key);
+            String bv = OsmUtils.getNamedOsmBoolean(c.boolValue);
+            if(k == null || (c.value != null && !k.equals(c.value))
                     || (bv != null && !bv.equals(OsmUtils.getNamedOsmBoolean(k))))
                 return false;
Index: unk/src/org/openstreetmap/josm/gui/mappaint/ElemStyleHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyleHandler.java	(revision 3804)
+++ 	(revision )
@@ -1,288 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.mappaint;
-
-import java.awt.Color;
-import java.util.Collection;
-import java.util.LinkedList;
-
-import javax.swing.ImageIcon;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.tools.ColorHelper;
-import org.xml.sax.Attributes;
-import org.xml.sax.helpers.DefaultHandler;
-
-public class ElemStyleHandler extends DefaultHandler
-{
-    private boolean inDoc, inRule, inCondition, inLine, inLineMod, inIcon, inArea, inScaleMax, inScaleMin;
-    private boolean hadLine, hadLineMod, hadIcon, hadArea;
-    private RuleElem rule = new RuleElem();
-
-    StyleSource style;
-
-    static class RuleElem {
-        Rule rule = new Rule();
-        Collection<Rule> rules;
-        long scaleMax;
-        long scaleMin;
-        LineElemStyle line = new LineElemStyle();
-        LineElemStyle linemod = new LineElemStyle();
-        AreaElemStyle area = new AreaElemStyle();
-        IconElemStyle icon = new IconElemStyle();
-        public void init()
-        {
-            rules = null;
-            scaleMax = 1000000000;
-            scaleMin = 0;
-            line.init();
-            rule.init();
-            linemod.init();
-            area.init();
-            icon.init();
-        }
-    }
-
-    public ElemStyleHandler(StyleSource style) {
-        this.style = style;
-        inDoc=inRule=inCondition=inLine=inIcon=inArea=false;
-        rule.init();
-    }
-
-    Color convertColor(String colString)
-    {
-        int i = colString.indexOf("#");
-        Color ret;
-        if (i < 0) {
-            ret = Main.pref.getColor("mappaint."+style.getPrefName()+"."+colString, Color.red);
-        } else if(i == 0) {
-            ret = ColorHelper.html2color(colString);
-        } else {
-            ret = Main.pref.getColor("mappaint."+style.getPrefName()+"."+colString.substring(0,i),
-                    ColorHelper.html2color(colString.substring(i)));
-        }
-        return ret;
-    }
-
-    @Override public void startDocument() {
-        inDoc = true;
-    }
-
-    @Override public void endDocument() {
-        inDoc = false;
-    }
-
-    private void error(String message) {
-        System.out.println(style.getDisplayString() + " (" + rule.rule.key + "=" + rule.rule.value + "): " + message);
-    }
-
-    private void startElementLine(String qName, Attributes atts, LineElemStyle line) {
-        for (int count=0; count<atts.getLength(); count++)
-        {
-            if(atts.getQName(count).equals("width"))
-            {
-                String val = atts.getValue(count);
-                if(val.startsWith("+"))
-                {
-                    line.setWidth(Integer.parseInt(val.substring(1)));
-                    line.widthMode = LineElemStyle.WidthMode.OFFSET;
-                }
-                else if(val.startsWith("-"))
-                {
-                    line.setWidth(Integer.parseInt(val));
-                    line.widthMode = LineElemStyle.WidthMode.OFFSET;
-                }
-                else if(val.endsWith("%"))
-                {
-                    line.setWidth(Integer.parseInt(val.substring(0, val.length()-1)));
-                    line.widthMode = LineElemStyle.WidthMode.PERCENT;
-                } else {
-                    line.setWidth(Integer.parseInt(val));
-                }
-            }
-            else if (atts.getQName(count).equals("colour")) {
-                line.color=convertColor(atts.getValue(count));
-            } else if (atts.getQName(count).equals("realwidth")) {
-                line.realWidth=Integer.parseInt(atts.getValue(count));
-            } else if (atts.getQName(count).equals("dashed")) {
-                float[] dashed;
-                try {
-                    String[] parts = atts.getValue(count).split(",");
-                    dashed = new float[parts.length];
-                    for (int i = 0; i < parts.length; i++) {
-                        dashed[i] = (Integer.parseInt(parts[i]));
-                    }
-                } catch (NumberFormatException nfe) {
-                    boolean isDashed = Boolean.parseBoolean(atts.getValue(count));
-                    if(isDashed) {
-                        dashed = new float[]{9};
-                    } else {
-                        dashed = new float[0];
-                    }
-                }
-                line.setDashed(dashed);
-            } else if (atts.getQName(count).equals("dashedcolour")) {
-                line.dashedColor=convertColor(atts.getValue(count));
-            } else if(atts.getQName(count).equals("priority")) {
-                line.priority = Integer.parseInt(atts.getValue(count));
-            } else if(atts.getQName(count).equals("mode")) {
-                line.over = !atts.getValue(count).equals("under");
-            } else {
-                error("The element \"" + qName + "\" has unknown attribute \"" + atts.getQName(count) + "\"!");
-            }
-        }
-    }
-
-    @Override public void startElement(String uri,String name, String qName, Attributes atts) {
-        if (inDoc==true)
-        {
-            if (qName.equals("rule")) {
-                inRule=true;
-            } else if (qName.equals("rules"))
-            {
-                if (style.name == null) {
-                    style.name = atts.getValue("name");
-                }
-                if (style.shortdescription == null) {
-                    style.shortdescription = atts.getValue("shortdescription");
-                }
-            }
-            else if (qName.equals("scale_max")) {
-                inScaleMax = true;
-            } else if (qName.equals("scale_min")) {
-                inScaleMin = true;
-            } else if (qName.equals("condition") && inRule)
-            {
-                inCondition=true;
-                Rule r = rule.rule;
-                if(r.key != null)
-                {
-                    if(rule.rules == null) {
-                        rule.rules = new LinkedList<Rule>();
-                    }
-                    rule.rules.add(new Rule(rule.rule));
-                    r = new Rule();
-                    rule.rules.add(r);
-                }
-                for (int count=0; count<atts.getLength(); count++)
-                {
-                    if(atts.getQName(count).equals("k")) {
-                        r.key = atts.getValue(count);
-                    } else if(atts.getQName(count).equals("v")) {
-                        r.value = atts.getValue(count);
-                    } else if(atts.getQName(count).equals("b")) {
-                        r.boolValue = atts.getValue(count);
-                    } else {
-                        error("The element \"" + qName + "\" has unknown attribute \"" + atts.getQName(count) + "\"!");
-                    }
-                }
-                if(r.key == null) {
-                    error("The condition has no key!");
-                }
-            }
-            else if (qName.equals("line"))
-            {
-                hadLine = inLine = true;
-                startElementLine(qName, atts, rule.line);
-                if(rule.line.widthMode != LineElemStyle.WidthMode.ABSOLUTE) {
-                    error("Relative widths are not possible for normal lines");
-                    rule.line.widthMode = LineElemStyle.WidthMode.ABSOLUTE;
-                }
-            }
-            else if (qName.equals("linemod"))
-            {
-                hadLineMod = inLineMod = true;
-                startElementLine(qName, atts, rule.linemod);
-            }
-            else if (qName.equals("icon"))
-            {
-                inIcon = true;
-                for (int count=0; count<atts.getLength(); count++)
-                {
-                    if (atts.getQName(count).equals("src")) {
-                        ImageIcon icon = MapPaintStyles.getIcon(atts.getValue(count), style.getPrefName());
-                        hadIcon = (icon != null);
-                        rule.icon.icon = icon;
-                    } else if (atts.getQName(count).equals("annotate")) {
-                        rule.icon.annotate = Boolean.parseBoolean (atts.getValue(count));
-                    } else if(atts.getQName(count).equals("priority")) {
-                        rule.icon.priority = Integer.parseInt(atts.getValue(count));
-                    } else {
-                        error("The element \"" + qName + "\" has unknown attribute \"" + atts.getQName(count) + "\"!");
-                    }
-                }
-            }
-            else if (qName.equals("area"))
-            {
-                hadArea = inArea = true;
-                for (int count=0; count<atts.getLength(); count++)
-                {
-                    if (atts.getQName(count).equals("colour")) {
-                        rule.area.color=convertColor(atts.getValue(count));
-                    } else if (atts.getQName(count).equals("closed")) {
-                        rule.area.closed=Boolean.parseBoolean(atts.getValue(count));
-                    } else if(atts.getQName(count).equals("priority")) {
-                        rule.area.priority = Integer.parseInt(atts.getValue(count));
-                    } else {
-                        error("The element \"" + qName + "\" has unknown attribute \"" + atts.getQName(count) + "\"!");
-                    }
-                }
-            } else {
-                error("The element \"" + qName + "\" is unknown!");
-            }
-        }
-    }
-
-    @Override public void endElement(String uri,String name, String qName)
-    {
-        if (inRule && qName.equals("rule"))
-        {
-            if(hadLine)
-            {
-                style.add(rule.rule, rule.rules,
-                        new LineElemStyle(rule.line, rule.scaleMax, rule.scaleMin));
-            }
-            if(hadLineMod)
-            {
-                style.addModifier(rule.rule, rule.rules,
-                        new LineElemStyle(rule.linemod, rule.scaleMax, rule.scaleMin));
-            }
-            if(hadIcon)
-            {
-                style.add(rule.rule, rule.rules,
-                        new IconElemStyle(rule.icon, rule.scaleMax, rule.scaleMin));
-            }
-            if(hadArea)
-            {
-                style.add(rule.rule, rule.rules,
-                        new AreaElemStyle(rule.area, rule.scaleMax, rule.scaleMin));
-            }
-            inRule = false;
-            hadLine = hadLineMod = hadIcon = hadArea = false;
-            rule.init();
-        }
-        else if (inCondition && qName.equals("condition")) {
-            inCondition = false;
-        } else if (inLine && qName.equals("line")) {
-            inLine = false;
-        } else if (inLineMod && qName.equals("linemod")) {
-            inLineMod = false;
-        } else if (inIcon && qName.equals("icon")) {
-            inIcon = false;
-        } else if (inArea && qName.equals("area")) {
-            inArea = false;
-        } else if (qName.equals("scale_max")) {
-            inScaleMax = false;
-        } else if (qName.equals("scale_min")) {
-            inScaleMin = false;
-        }
-    }
-
-    @Override public void characters(char ch[], int start, int length)
-    {
-        if (inScaleMax == true) {
-            rule.scaleMax = Long.parseLong(new String(ch, start, length));
-        } else if (inScaleMin == true) {
-            rule.scaleMin = Long.parseLong(new String(ch, start, length));
-        }
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/IconElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/IconElemStyle.java	(revision 3804)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/IconElemStyle.java	(revision 3805)
@@ -22,5 +22,5 @@
         this.maxScale = maxScale;
         this.minScale = minScale;
-        this.rules = i.rules;
+        this.conditions = i.conditions;
     }
     public IconElemStyle() { init(); }
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 3804)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 3805)
@@ -45,5 +45,5 @@
         this.maxScale = maxScale;
         this.minScale = minScale;
-        this.rules = s.rules;
+        this.conditions = s.conditions;
     }
 
@@ -60,5 +60,5 @@
         this.maxScale = s.maxScale;
         this.minScale = s.minScale;
-        this.rules = s.rules;
+        this.conditions = s.conditions;
 
         this.overlays = overlays;
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 3804)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 3805)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.gui.mappaint;
 
+import org.openstreetmap.josm.gui.mappaint.xml.XmlStyleSourceHandler;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -78,5 +79,5 @@
             StyleSource style = new StyleSource(entry);
             try {
-                XmlObjectParser parser = new XmlObjectParser(new ElemStyleHandler(style));
+                XmlObjectParser parser = new XmlObjectParser(new XmlStyleSourceHandler(style));
                 MirroredInputStream in = new MirroredInputStream(entry.url);
                 InputStream zip = in.getZipEntry("xml","style");
Index: unk/src/org/openstreetmap/josm/gui/mappaint/Rule.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/Rule.java	(revision 3804)
+++ 	(revision )
@@ -1,44 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.mappaint;
-
-import org.openstreetmap.josm.data.osm.OsmUtils;
-
-public class Rule
-{
-    String key;
-    String value;
-    String boolValue;
-
-    public Rule()
-    {
-      init();
-    }
-    public Rule(Rule r)
-    {
-      key = r.key;
-      value = r.value;
-      boolValue = r.boolValue;
-    }
-    public String getKey()
-    {
-        if(value != null)
-            return "n" + key + "=" + value;
-        else if(boolValue != null)
-            return "b" + key  + "=" + OsmUtils.getNamedOsmBoolean(boolValue);
-        else
-            return "x" + key;
-    }
-    public void init()
-    {
-      key = value = boolValue = null;
-    }
-
-    public String toString()
-    {
-      return "Rule["+key+","+(boolValue != null ? "b="+boolValue:"v="+value)+"]";
-    }
-    public String toCode()
-    {
-      return "[k="+key+(boolValue != null ? ",b="+boolValue:",v="+value)+"]";
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java	(revision 3804)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java	(revision 3805)
@@ -10,8 +10,10 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.mappaint.xml.XmlCondition;
 import org.openstreetmap.josm.gui.preferences.SourceEntry;
 
@@ -172,12 +174,12 @@
     }
 
-    public void add(Rule r, Collection<Rule> rules, LineElemStyle style) {
-        if(rules != null)
-        {
-            style.rules = rules;
+    public void add(XmlCondition c, Collection<XmlCondition> conditions, LineElemStyle style) {
+        if(conditions != null)
+        {
+            style.conditions = conditions;
             linesList.add(style);
         }
         else {
-            String key = r.getKey();
+            String key = c.getKey();
             style.code = key;
             lines.put(key, style);
@@ -185,13 +187,13 @@
     }
 
-    public void addModifier(Rule r, Collection<Rule> rules, LineElemStyle style) {
-        if(rules != null)
-        {
-            style.rules = rules;
+    public void addModifier(XmlCondition c, Collection<XmlCondition> conditions, LineElemStyle style) {
+        if(conditions != null)
+        {
+            style.conditions = conditions;
             modifiersList.add(style);
         }
         else
         {
-            String key = r.getKey();
+            String key = c.getKey();
             style.code = key;
             modifiers.put(key, style);
@@ -199,13 +201,13 @@
     }
 
-    public void add(Rule r, Collection<Rule> rules, AreaElemStyle style) {
-        if(rules != null)
-        {
-            style.rules = rules;
+    public void add(XmlCondition c, Collection<XmlCondition> conditions, AreaElemStyle style) {
+        if(conditions != null)
+        {
+            style.conditions = conditions;
             areasList.add(style);
         }
         else
         {
-            String key = r.getKey();
+            String key = c.getKey();
             style.code = key;
             areas.put(key, style);
@@ -213,13 +215,13 @@
     }
 
-    public void add(Rule r, Collection<Rule> rules, IconElemStyle style) {
-        if(rules != null)
-        {
-            style.rules = rules;
+    public void add(XmlCondition c, Collection<XmlCondition> conditions, IconElemStyle style) {
+        if(conditions != null)
+        {
+            style.conditions = conditions;
             iconsList.add(style);
         }
         else
         {
-            String key = r.getKey();
+            String key = c.getKey();
             style.code = key;
             icons.put(key, style);
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlCondition.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlCondition.java	(revision 3805)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlCondition.java	(revision 3805)
@@ -0,0 +1,44 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint.xml;
+
+import org.openstreetmap.josm.data.osm.OsmUtils;
+
+public class XmlCondition
+{
+    public String key;
+    public String value;
+    public String boolValue;
+
+    public XmlCondition()
+    {
+      init();
+    }
+    public XmlCondition(XmlCondition c)
+    {
+      key = c.key;
+      value = c.value;
+      boolValue = c.boolValue;
+    }
+    public String getKey()
+    {
+        if(value != null)
+            return "n" + key + "=" + value;
+        else if(boolValue != null)
+            return "b" + key  + "=" + OsmUtils.getNamedOsmBoolean(boolValue);
+        else
+            return "x" + key;
+    }
+    public void init()
+    {
+      key = value = boolValue = null;
+    }
+
+    public String toString()
+    {
+      return "Rule["+key+","+(boolValue != null ? "b="+boolValue:"v="+value)+"]";
+    }
+    public String toCode()
+    {
+      return "[k="+key+(boolValue != null ? ",b="+boolValue:",v="+value)+"]";
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSourceHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSourceHandler.java	(revision 3805)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSourceHandler.java	(revision 3805)
@@ -0,0 +1,293 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint.xml;
+
+import java.awt.Color;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.mappaint.AreaElemStyle;
+import org.openstreetmap.josm.gui.mappaint.IconElemStyle;
+import org.openstreetmap.josm.gui.mappaint.LineElemStyle;
+import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
+import org.openstreetmap.josm.gui.mappaint.StyleSource;
+import org.openstreetmap.josm.tools.ColorHelper;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class XmlStyleSourceHandler extends DefaultHandler
+{
+    private boolean inDoc, inRule, inCondition, inLine, inLineMod, inIcon, inArea, inScaleMax, inScaleMin;
+    private boolean hadLine, hadLineMod, hadIcon, hadArea;
+    private RuleElem rule = new RuleElem();
+
+    StyleSource style;
+
+    static class RuleElem {
+        XmlCondition cond = new XmlCondition();
+        Collection<XmlCondition> conditions;
+        long scaleMax;
+        long scaleMin;
+        LineElemStyle line = new LineElemStyle();
+        LineElemStyle linemod = new LineElemStyle();
+        AreaElemStyle area = new AreaElemStyle();
+        IconElemStyle icon = new IconElemStyle();
+        public void init()
+        {
+            conditions = null;
+            scaleMax = 1000000000;
+            scaleMin = 0;
+            line.init();
+            cond.init();
+            linemod.init();
+            area.init();
+            icon.init();
+        }
+    }
+
+    public XmlStyleSourceHandler(StyleSource style) {
+        this.style = style;
+        inDoc=inRule=inCondition=inLine=inIcon=inArea=false;
+        rule.init();
+    }
+
+    Color convertColor(String colString)
+    {
+        int i = colString.indexOf("#");
+        Color ret;
+        if (i < 0) {
+            ret = Main.pref.getColor("mappaint."+style.getPrefName()+"."+colString, Color.red);
+        } else if(i == 0) {
+            ret = ColorHelper.html2color(colString);
+        } else {
+            ret = Main.pref.getColor("mappaint."+style.getPrefName()+"."+colString.substring(0,i),
+                    ColorHelper.html2color(colString.substring(i)));
+        }
+        return ret;
+    }
+
+    @Override public void startDocument() {
+        inDoc = true;
+    }
+
+    @Override public void endDocument() {
+        inDoc = false;
+    }
+
+    private void error(String message) {
+        System.out.println(style.getDisplayString() + " (" + rule.cond.key + "=" + rule.cond.value + "): " + message);
+    }
+
+    private void startElementLine(String qName, Attributes atts, LineElemStyle line) {
+        for (int count=0; count<atts.getLength(); count++)
+        {
+            if(atts.getQName(count).equals("width"))
+            {
+                String val = atts.getValue(count);
+                if(val.startsWith("+"))
+                {
+                    line.setWidth(Integer.parseInt(val.substring(1)));
+                    line.widthMode = LineElemStyle.WidthMode.OFFSET;
+                }
+                else if(val.startsWith("-"))
+                {
+                    line.setWidth(Integer.parseInt(val));
+                    line.widthMode = LineElemStyle.WidthMode.OFFSET;
+                }
+                else if(val.endsWith("%"))
+                {
+                    line.setWidth(Integer.parseInt(val.substring(0, val.length()-1)));
+                    line.widthMode = LineElemStyle.WidthMode.PERCENT;
+                } else {
+                    line.setWidth(Integer.parseInt(val));
+                }
+            }
+            else if (atts.getQName(count).equals("colour")) {
+                line.color=convertColor(atts.getValue(count));
+            } else if (atts.getQName(count).equals("realwidth")) {
+                line.realWidth=Integer.parseInt(atts.getValue(count));
+            } else if (atts.getQName(count).equals("dashed")) {
+                float[] dashed;
+                try {
+                    String[] parts = atts.getValue(count).split(",");
+                    dashed = new float[parts.length];
+                    for (int i = 0; i < parts.length; i++) {
+                        dashed[i] = (Integer.parseInt(parts[i]));
+                    }
+                } catch (NumberFormatException nfe) {
+                    boolean isDashed = Boolean.parseBoolean(atts.getValue(count));
+                    if(isDashed) {
+                        dashed = new float[]{9};
+                    } else {
+                        dashed = new float[0];
+                    }
+                }
+                line.setDashed(dashed);
+            } else if (atts.getQName(count).equals("dashedcolour")) {
+                line.dashedColor=convertColor(atts.getValue(count));
+            } else if(atts.getQName(count).equals("priority")) {
+                line.priority = Integer.parseInt(atts.getValue(count));
+            } else if(atts.getQName(count).equals("mode")) {
+                line.over = !atts.getValue(count).equals("under");
+            } else {
+                error("The element \"" + qName + "\" has unknown attribute \"" + atts.getQName(count) + "\"!");
+            }
+        }
+    }
+
+    @Override public void startElement(String uri,String name, String qName, Attributes atts) {
+        if (inDoc==true)
+        {
+            if (qName.equals("rule")) {
+                inRule=true;
+            } else if (qName.equals("rules"))
+            {
+                if (style.name == null) {
+                    style.name = atts.getValue("name");
+                }
+                if (style.shortdescription == null) {
+                    style.shortdescription = atts.getValue("shortdescription");
+                }
+            }
+            else if (qName.equals("scale_max")) {
+                inScaleMax = true;
+            } else if (qName.equals("scale_min")) {
+                inScaleMin = true;
+            } else if (qName.equals("condition") && inRule)
+            {
+                inCondition=true;
+                XmlCondition c = rule.cond;
+                if(c.key != null)
+                {
+                    if(rule.conditions == null) {
+                        rule.conditions = new LinkedList<XmlCondition>();
+                    }
+                    rule.conditions.add(new XmlCondition(rule.cond));
+                    c = new XmlCondition();
+                    rule.conditions.add(c);
+                }
+                for (int count=0; count<atts.getLength(); count++)
+                {
+                    if(atts.getQName(count).equals("k")) {
+                        c.key = atts.getValue(count);
+                    } else if(atts.getQName(count).equals("v")) {
+                        c.value = atts.getValue(count);
+                    } else if(atts.getQName(count).equals("b")) {
+                        c.boolValue = atts.getValue(count);
+                    } else {
+                        error("The element \"" + qName + "\" has unknown attribute \"" + atts.getQName(count) + "\"!");
+                    }
+                }
+                if(c.key == null) {
+                    error("The condition has no key!");
+                }
+            }
+            else if (qName.equals("line"))
+            {
+                hadLine = inLine = true;
+                startElementLine(qName, atts, rule.line);
+                if(rule.line.widthMode != LineElemStyle.WidthMode.ABSOLUTE) {
+                    error("Relative widths are not possible for normal lines");
+                    rule.line.widthMode = LineElemStyle.WidthMode.ABSOLUTE;
+                }
+            }
+            else if (qName.equals("linemod"))
+            {
+                hadLineMod = inLineMod = true;
+                startElementLine(qName, atts, rule.linemod);
+            }
+            else if (qName.equals("icon"))
+            {
+                inIcon = true;
+                for (int count=0; count<atts.getLength(); count++)
+                {
+                    if (atts.getQName(count).equals("src")) {
+                        ImageIcon icon = MapPaintStyles.getIcon(atts.getValue(count), style.getPrefName());
+                        hadIcon = (icon != null);
+                        rule.icon.icon = icon;
+                    } else if (atts.getQName(count).equals("annotate")) {
+                        rule.icon.annotate = Boolean.parseBoolean (atts.getValue(count));
+                    } else if(atts.getQName(count).equals("priority")) {
+                        rule.icon.priority = Integer.parseInt(atts.getValue(count));
+                    } else {
+                        error("The element \"" + qName + "\" has unknown attribute \"" + atts.getQName(count) + "\"!");
+                    }
+                }
+            }
+            else if (qName.equals("area"))
+            {
+                hadArea = inArea = true;
+                for (int count=0; count<atts.getLength(); count++)
+                {
+                    if (atts.getQName(count).equals("colour")) {
+                        rule.area.color=convertColor(atts.getValue(count));
+                    } else if (atts.getQName(count).equals("closed")) {
+                        rule.area.closed=Boolean.parseBoolean(atts.getValue(count));
+                    } else if(atts.getQName(count).equals("priority")) {
+                        rule.area.priority = Integer.parseInt(atts.getValue(count));
+                    } else {
+                        error("The element \"" + qName + "\" has unknown attribute \"" + atts.getQName(count) + "\"!");
+                    }
+                }
+            } else {
+                error("The element \"" + qName + "\" is unknown!");
+            }
+        }
+    }
+
+    @Override public void endElement(String uri,String name, String qName)
+    {
+        if (inRule && qName.equals("rule"))
+        {
+            if(hadLine)
+            {
+                style.add(rule.cond, rule.conditions,
+                        new LineElemStyle(rule.line, rule.scaleMax, rule.scaleMin));
+            }
+            if(hadLineMod)
+            {
+                style.addModifier(rule.cond, rule.conditions,
+                        new LineElemStyle(rule.linemod, rule.scaleMax, rule.scaleMin));
+            }
+            if(hadIcon)
+            {
+                style.add(rule.cond, rule.conditions,
+                        new IconElemStyle(rule.icon, rule.scaleMax, rule.scaleMin));
+            }
+            if(hadArea)
+            {
+                style.add(rule.cond, rule.conditions,
+                        new AreaElemStyle(rule.area, rule.scaleMax, rule.scaleMin));
+            }
+            inRule = false;
+            hadLine = hadLineMod = hadIcon = hadArea = false;
+            rule.init();
+        }
+        else if (inCondition && qName.equals("condition")) {
+            inCondition = false;
+        } else if (inLine && qName.equals("line")) {
+            inLine = false;
+        } else if (inLineMod && qName.equals("linemod")) {
+            inLineMod = false;
+        } else if (inIcon && qName.equals("icon")) {
+            inIcon = false;
+        } else if (inArea && qName.equals("area")) {
+            inArea = false;
+        } else if (qName.equals("scale_max")) {
+            inScaleMax = false;
+        } else if (qName.equals("scale_min")) {
+            inScaleMin = false;
+        }
+    }
+
+    @Override public void characters(char ch[], int start, int length)
+    {
+        if (inScaleMax == true) {
+            rule.scaleMax = Long.parseLong(new String(ch, start, length));
+        } else if (inScaleMin == true) {
+            rule.scaleMin = Long.parseLong(new String(ch, start, length));
+        }
+    }
+}
