Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2675)
@@ -1266,3 +1266,7 @@
         return incomplete;
     }
+
+    public boolean isSelected() {
+        return dataSet != null && dataSet.isSelected(this);
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java	(revision 2675)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java	(revision 2675)
@@ -0,0 +1,144 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.visitor.paint;
+
+import java.awt.Color;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
+import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
+
+public class MapPaintSettings implements PreferenceChangedListener {
+
+    public static final MapPaintSettings INSTANCE = new MapPaintSettings();
+
+    private boolean useRealWidth;
+    private boolean showDirectionArrow;
+    private boolean showRelevantDirectionsOnly;
+    private int defaultSegmentWidth;
+    private boolean showOrderNumber;
+    private boolean showHeadArrowOnly;
+    private int showNamesDistance;
+    private int useStrokesDistance;
+    private int showIconsDistance;
+    private int selectedNodeSize;
+    private int taggedNodeSize;
+    private int unselectedNodeSize;
+    private boolean fillSelectedNode;
+    private boolean fillUnselectedNode;
+
+    private Color selectedColor;
+    private Color highlightColor;
+    private Color inactiveColor;
+    private Color nodeColor;
+
+    private MapPaintSettings() {
+        load();
+        Main.pref.addPreferenceChangeListener(this);
+    }
+
+    private void load() {
+        showDirectionArrow = Main.pref.getBoolean("draw.segment.direction", true);
+        showRelevantDirectionsOnly = Main.pref.getBoolean("draw.segment.relevant_directions_only", true);
+        useRealWidth = Main.pref.getBoolean("mappaint.useRealWidth", false);
+        defaultSegmentWidth = Main.pref.getInteger("mappaint.segment.default-width", 2);
+
+        selectedColor = PaintColors.SELECTED.get();
+        highlightColor = PaintColors.HIGHLIGHT.get();
+        inactiveColor = PaintColors.INACTIVE.get();
+        nodeColor = PaintColors.NODE.get();
+
+        showOrderNumber = Main.pref.getBoolean("draw.segment.order_number", false);
+        showHeadArrowOnly = Main.pref.getBoolean("draw.segment.head_only", false);
+
+        showNamesDistance = Main.pref.getInteger("mappaint.shownames", 10000000);
+        useStrokesDistance = Main.pref.getInteger("mappaint.strokes", 10000000);
+        showIconsDistance = Main.pref.getInteger("mappaint.showicons", 10000000);
+
+        selectedNodeSize = Main.pref.getInteger("mappaint.node.selected-size", 4);
+        unselectedNodeSize = Main.pref.getInteger("mappaint.node.unselected-size", 2);
+        taggedNodeSize = Main.pref.getInteger("mappaint.node.tagged-size", 4);
+        fillSelectedNode = Main.pref.getBoolean("mappaint.node.fill-selected", true);
+        fillUnselectedNode = Main.pref.getBoolean("mappaint.node.fill-unselected", false);
+    }
+
+    public void preferenceChanged(PreferenceChangeEvent e) {
+        load();
+    }
+
+
+    public boolean isUseRealWidth() {
+        return useRealWidth;
+    }
+
+    public boolean isShowDirectionArrow() {
+        return showDirectionArrow;
+    }
+
+    public boolean isShowRelevantDirectionsOnly() {
+        return showRelevantDirectionsOnly;
+    }
+
+    public int getDefaultSegmentWidth() {
+        return defaultSegmentWidth;
+    }
+
+    public Color getSelectedColor() {
+        return selectedColor;
+    }
+
+    public Color getHighlightColor() {
+        return highlightColor;
+    }
+
+    public Color getInactiveColor() {
+        return inactiveColor;
+    }
+
+    public boolean isShowOrderNumber() {
+        return showOrderNumber;
+    }
+
+    public void setShowHeadArrowOnly(boolean showHeadArrowOnly) {
+        this.showHeadArrowOnly = showHeadArrowOnly;
+    }
+
+    public boolean isShowHeadArrowOnly() {
+        return showHeadArrowOnly;
+    }
+
+    public int getShowNamesDistance() {
+        return showNamesDistance;
+    }
+
+    public int getUseStrokesDistance() {
+        return useStrokesDistance;
+    }
+
+    public Color getNodeColor() {
+        return nodeColor;
+    }
+
+    public int getShowIconsDistance() {
+        return showIconsDistance;
+    }
+
+    public int getSelectedNodeSize() {
+        return selectedNodeSize;
+    }
+
+    public int getTaggedNodeSize() {
+        return taggedNodeSize;
+    }
+
+    public int getUnselectedNodeSize() {
+        return unselectedNodeSize;
+    }
+
+    public boolean isFillSelectedNode() {
+        return fillSelectedNode;
+    }
+
+    public boolean isFillUnselectedNode() {
+        return fillUnselectedNode;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java	(revision 2675)
@@ -6,5 +6,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.Point;
@@ -13,5 +12,4 @@
 import java.awt.geom.Point2D;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -41,54 +39,26 @@
 import org.openstreetmap.josm.gui.mappaint.LineElemStyle;
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
-import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.gui.mappaint.SimpleNodeElemStyle;
 
 public class MapPaintVisitor implements PaintVisitor {
 
-    protected Graphics2D g;
-    protected NavigatableComponent nc;
-
-    protected boolean useRealWidth;
-    protected boolean zoomLevelDisplay;
-    protected boolean drawMultipolygon;
-    protected boolean drawRestriction;
-    protected boolean leftHandTraffic;
-    protected int showNames;
-    protected int showIcons;
-    protected int useStrokes;
-    protected int fillAlpha;
-    protected Color untaggedColor;
-    protected Color textColor;
-    protected Color areaTextColor;
-    protected ElemStyles.StyleSet styles;
-    protected double circum;
-    protected double dist;
-    protected boolean useStyleCache;
+    private Graphics2D g;
+    private NavigatableComponent nc;
+
+    private boolean zoomLevelDisplay;
+    private boolean drawMultipolygon;
+    private boolean drawRestriction;
+    private boolean leftHandTraffic;
+    private ElemStyles.StyleSet styles;
+    private double circum;
+    private double dist;
+    private boolean useStyleCache;
     private static int paintid = 0;
     private EastNorth minEN;
     private EastNorth maxEN;
     private MapPainter painter;
-    protected Collection<String> regionalNameOrder;
-
-    public boolean inactive;
-    protected boolean fillSelectedNode;
-    protected boolean fillUnselectedNode;
-    protected int defaultSegmentWidth;
-    protected boolean showOrderNumber;
-
-    protected boolean showRelevantDirectionsOnly;
-    protected boolean showHeadArrowOnly;
-    protected boolean showDirectionArrow;
-
-    protected int selectedNodeRadius;
-    protected int selectedNodeSize;
-    protected int taggedNodeSize;
-    protected int taggedNodeRadius;
-    protected int unselectedNodeRadius;
-    protected int unselectedNodeSize;
-
-    protected Color selectedColor;
-    protected Color highlightColor;
-    protected Color inactiveColor;
-    protected Color nodeColor;
+    private MapPaintSettings paintSettings;
+
+    private boolean inactive;
 
     protected boolean isZoomOk(ElemStyle e) {
@@ -112,4 +82,9 @@
             }
         }
+
+        if (osm.mappaintStyle == null && osm instanceof Node) {
+            osm.mappaintStyle = SimpleNodeElemStyle.INSTANCE;
+        }
+
         return osm.mappaintStyle;
     }
@@ -145,28 +120,8 @@
             return;
 
-        IconElemStyle nodeStyle = (IconElemStyle)getPrimitiveStyle(n);
-
-        if (nodeStyle != null && isZoomOk(nodeStyle) && showIcons > dist) {
-            painter.drawNodeIcon(n, (inactive || n.isDisabled())?nodeStyle.getDisabledIcon():nodeStyle.icon,
-                    nodeStyle.annotate, data.isSelected(n), getNodeName(n));
-        } else {
-            if (isZoomOk(null)) {
-                if (n.highlighted) {
-                    painter.drawNode(n, highlightColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode,
-                            getNodeName(n));
-                } else if (data.isSelected(n)) {
-                    painter.drawNode(n, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode,
-                            getNodeName(n));
-                } else if (n.isTagged()) {
-                    painter.drawNode(n, nodeColor, taggedNodeSize, taggedNodeRadius, fillUnselectedNode,
-                            getNodeName(n));
-                } else if (inactive || n.isDisabled()) {
-                    painter.drawNode(n, inactiveColor, unselectedNodeSize, unselectedNodeRadius, fillUnselectedNode,
-                            getNodeName(n));
-                } else {
-                    painter.drawNode(n, nodeColor, unselectedNodeSize, unselectedNodeRadius, fillUnselectedNode,
-                            getNodeName(n));
-                }
-            }
+        ElemStyle nodeStyle = getPrimitiveStyle(n);
+
+        if (isZoomOk(nodeStyle)) {
+            nodeStyle.paintPrimitive(n, paintSettings, painter, n.isSelected());
         }
     }
@@ -212,119 +167,21 @@
             return;
 
-        if(wayStyle==null)
-        {
-            /* way without style */
-            drawWay(w, null, untaggedColor, data.isSelected(w));
-        }
-        else if(wayStyle instanceof LineElemStyle)
-        {
-            /* way with line style */
-            drawWay(w, (LineElemStyle)wayStyle, untaggedColor, data.isSelected(w));
-        }
-        else if (wayStyle instanceof AreaElemStyle)
-        {
+        if (wayStyle == null) {
+            wayStyle = LineElemStyle.UNTAGGED_WAY;
+        }
+
+        if(wayStyle instanceof LineElemStyle) {
+            wayStyle.paintPrimitive(w, paintSettings, painter, data.isSelected(w));
+        } else if (wayStyle instanceof AreaElemStyle) {
             AreaElemStyle areaStyle = (AreaElemStyle) wayStyle;
             /* way with area style */
             if (fillAreas > dist)
             {
-                painter.drawArea(getPolygon(w), (data.isSelected(w) ? selectedColor : areaStyle.color), getWayName(w));
+                painter.drawArea(getPolygon(w), (data.isSelected(w) ? paintSettings.getSelectedColor() : areaStyle.color), painter.getWayName(w));
                 if(!w.isClosed()) {
                     putError(w, tr("Area style way is not closed."), true);
                 }
             }
-            drawWay(w, areaStyle.line, areaStyle.color, data.isSelected(w));
-        }
-    }
-
-    public void drawWay(Way w, LineElemStyle l, Color color, boolean selected) {
-        /* show direction arrows, if draw.segment.relevant_directions_only is not set,
-           the way is tagged with a direction key
-           (even if the tag is negated as in oneway=false) or the way is selected */
-        boolean showDirection = data.isSelected(w) || ((!useRealWidth) && (showDirectionArrow
-                && (!showRelevantDirectionsOnly || w.hasDirectionKeys())));
-        /* head only takes over control if the option is true,
-           the direction should be shown at all and not only because it's selected */
-        boolean showOnlyHeadArrowOnly = showDirection && !data.isSelected(w) && showHeadArrowOnly;
-        int width = defaultSegmentWidth;
-        int realWidth = 0; /* the real width of the element in meters */
-        float dashed[] = new float[0];
-        Color dashedColor = null;
-        Node lastN;
-
-        if(l != null) {
-            if (l.color != null) {
-                color = l.color;
-            }
-            width = l.width;
-            realWidth = l.realWidth;
-            dashed = l.getDashed();
-            dashedColor = l.dashedColor;
-        }
-        if(selected) {
-            color = selectedColor;
-        }
-        if (realWidth > 0 && useRealWidth && !showDirection) {
-
-            /* if we have a "width" tag, try use it */
-            /* (this might be slow and could be improved by caching the value in the Way, on the other hand only used if "real width" is enabled) */
-            String widthTag = w.get("width");
-            if(widthTag == null) {
-                widthTag = w.get("est_width");
-            }
-            if(widthTag != null) {
-                try {
-                    realWidth = Integer.parseInt(widthTag);
-                }
-                catch(NumberFormatException nfe) {
-                }
-            }
-
-            int tmpWidth = (int) (100 /  (float) (circum / realWidth));
-            if (tmpWidth > width) {
-                width = tmpWidth;
-            }
-        }
-
-        if(w.highlighted) {
-            color = highlightColor;
-        } else if(data.isSelected(w)) {
-            color = selectedColor;
-        } else if(w.isDisabled()) {
-            color = inactiveColor;
-        }
-
-        /* draw overlays under the way */
-        if(l != null && l.overlays != null) {
-            for(LineElemStyle s : l.overlays) {
-                if(!s.over) {
-                    painter.drawWay(w, s.color != null && !data.isSelected(w) ? s.color : color, s.getWidth(width),
-                            s.getDashed(), s.dashedColor, false, false);
-                }
-            }
-        }
-
-        /* draw the way */
-        painter.drawWay(w, color, width, dashed, dashedColor, showDirection, showOnlyHeadArrowOnly);
-
-        /* draw overlays above the way */
-        if(l != null && l.overlays != null)  {
-            for(LineElemStyle s : l.overlays) {
-                if(s.over) {
-                    painter.drawWay(w, s.color != null && !data.isSelected(w) ? s.color : color, s.getWidth(width),
-                            s.getDashed(), s.dashedColor, false, false);
-                }
-            }
-        }
-
-        if(showOrderNumber) {
-            int orderNumber = 0;
-            lastN = null;
-            for(Node n : w.getNodes()) {
-                if(lastN != null) {
-                    orderNumber++;
-                    drawOrderNumber(lastN, n, orderNumber);
-                }
-                lastN = n;
-            }
+            areaStyle.getLineStyle().paintPrimitive(w, paintSettings, painter, data.isSelected(w));
         }
     }
@@ -441,26 +298,19 @@
         if(osm instanceof Way)
         {
-            if(style instanceof AreaElemStyle)
-            {
+            if(style instanceof AreaElemStyle) {
                 Way way = (Way)osm;
                 AreaElemStyle areaStyle = (AreaElemStyle)style;
-                drawWay(way, areaStyle.line, selectedColor, true);
+                areaStyle.getLineStyle().paintPrimitive(way, paintSettings, painter, true);
                 if(area) {
-                    painter.drawArea(getPolygon(way), (areaselected ? selectedColor : areaStyle.color), getWayName(way));
-                }
-            }
-            else
-            {
-                drawWay((Way)osm, (LineElemStyle)style, selectedColor, true);
+                    painter.drawArea(getPolygon(way), (areaselected ? paintSettings.getSelectedColor() : areaStyle.color), painter.getWayName(way));
+                }
+            } else {
+                style.paintPrimitive(osm, paintSettings, painter, true);
             }
         }
         else if(osm instanceof Node)
         {
-            if(style != null && isZoomOk(style)) {
-                painter.drawNodeIcon((Node)osm, ((IconElemStyle)style).icon,
-                        ((IconElemStyle)style).annotate, true, getNodeName((Node)osm));
-            } else if (isZoomOk(null)) {
-                painter.drawNode((Node)osm, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode,
-                        getNodeName((Node)osm));
+            if(isZoomOk(style)) {
+                style.paintPrimitive(osm, paintSettings, painter, true);
             }
         }
@@ -917,5 +767,5 @@
 
                     boolean selected = pd.selected || data.isSelected(pd.way) || data.isSelected(r);
-                    painter.drawArea(p, selected ? selectedColor : areaStyle.color, null);
+                    painter.drawArea(p, selected ? paintSettings.getSelectedColor() : areaStyle.color, null);
                     visible = true;
                 }
@@ -934,7 +784,6 @@
                             || outer.size() == 0))
                     {
-                        drawWay(wInner, ((AreaElemStyle)wayStyle).line,
-                                ((AreaElemStyle)wayStyle).color, data.isSelected(wInner)
-                                || data.isSelected(r));
+                        ((AreaElemStyle)wayStyle).getLineStyle().paintPrimitive(wInner, paintSettings, painter, (data.isSelected(wInner)
+                                || data.isSelected(r)));
                     }
                     wInner.mappaintDrawnCode = paintid;
@@ -968,7 +817,5 @@
                     if(zoomok)
                     {
-                        drawWay(wOuter, ((AreaElemStyle)wayStyle).line,
-                                ((AreaElemStyle)wayStyle).color, data.isSelected(wOuter)
-                                || data.isSelected(r));
+                        ((AreaElemStyle)wayStyle).getLineStyle().paintPrimitive(wOuter, paintSettings, painter, (data.isSelected(wOuter) || data.isSelected(r)));
                     }
                     wOuter.mappaintDrawnCode = paintid;
@@ -1043,46 +890,4 @@
         }
         return Math.abs(sum/2.0);
-    }
-
-    protected String getNodeName(Node n) {
-        if (showNames > dist) {
-            String name = null;
-            if (n.hasKeys()) {
-                for (String rn : regionalNameOrder) {
-                    name = n.get(rn);
-                    if (name != null) {
-                        break;
-                    }
-                }
-            }
-            return name;
-        } else
-            return null;
-    }
-
-    protected String getWayName(Way w) {
-        if (showNames > dist) {
-            String name = null;
-            if (w.hasKeys()) {
-                for (String rn : regionalNameOrder) {
-                    name = w.get(rn);
-                    if (name != null) {
-                        break;
-                    }
-                }
-            }
-            return name;
-        } else
-            return null;
-    }
-
-    public void getColors() {
-        selectedColor  = PaintColors.SELECTED.get();
-        highlightColor = PaintColors.HIGHLIGHT.get();
-        inactiveColor = PaintColors.INACTIVE.get();
-        nodeColor = PaintColors.NODE.get();
-        untaggedColor = PaintColors.UNTAGGED.get();
-        textColor = PaintColors.TEXT.get();
-        areaTextColor = PaintColors.AREA_TEXT.get();
     }
 
@@ -1113,29 +918,8 @@
         useStyleCache = Main.pref.getBoolean("mappaint.cache", true);
         int fillAreas = Main.pref.getInteger("mappaint.fillareas", 10000000);
-        fillAlpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fillalpha", 50))));
-        showNames = Main.pref.getInteger("mappaint.shownames", 10000000);
-        showIcons = Main.pref.getInteger("mappaint.showicons", 10000000);
-        useStrokes = Main.pref.getInteger("mappaint.strokes", 10000000);
         LatLon ll1 = nc.getLatLon(0, 0);
         LatLon ll2 = nc.getLatLon(100, 0);
         dist = ll1.greatCircleDistance(ll2);
 
-        getColors();
-
-        showDirectionArrow = Main.pref.getBoolean("draw.segment.direction", true);
-        showRelevantDirectionsOnly = Main.pref.getBoolean("draw.segment.relevant_directions_only", true);
-        showHeadArrowOnly = Main.pref.getBoolean("draw.segment.head_only", false);
-        showOrderNumber = Main.pref.getBoolean("draw.segment.order_number", false);
-        selectedNodeRadius = Main.pref.getInteger("mappaint.node.selected-size", 5) / 2;
-        selectedNodeSize = selectedNodeRadius * 2;
-        unselectedNodeRadius = Main.pref.getInteger("mappaint.node.unselected-size", 3) / 2;
-        unselectedNodeSize = unselectedNodeRadius * 2;
-        taggedNodeRadius = Main.pref.getInteger("mappaint.node.tagged-size", 5) / 2;
-        taggedNodeSize = taggedNodeRadius * 2;
-        defaultSegmentWidth = Main.pref.getInteger("mappaint.segment.default-width", 2);
-        fillSelectedNode = Main.pref.getBoolean("mappaint.node.fill-selected", true);
-        fillUnselectedNode = Main.pref.getBoolean("mappaint.node.fill-unselected", false);
-
-        useRealWidth = Main.pref.getBoolean("mappaint.useRealWidth", false);
         zoomLevelDisplay = Main.pref.getBoolean("mappaint.zoomLevelDisplay", false);
         circum = Main.map.mapView.getDist100Pixel();
@@ -1144,10 +928,9 @@
         drawRestriction = Main.pref.getBoolean("mappaint.restriction", true);
         leftHandTraffic = Main.pref.getBoolean("mappaint.lefthandtraffic", false);
-        String[] names = {"name:" + LanguageInfo.getJOSMLocaleCode(), "name", "int_name", "ref", "operator", "brand", "addr:housenumber"};
         minEN = nc.getEastNorth(0, nc.getHeight() - 1);
         maxEN = nc.getEastNorth(nc.getWidth() - 1, 0);
-        regionalNameOrder = Main.pref.getCollection("mappaint.nameOrder", Arrays.asList(names));
-
-        this.painter = new MapPainter(g, inactive, nc, useStrokes > dist, virtual);
+
+        this.paintSettings = MapPaintSettings.INSTANCE;
+        this.painter = new MapPainter(paintSettings, g, inactive, nc, virtual, dist, circum);
 
         data.clearErrors();
@@ -1235,14 +1018,4 @@
     }
 
-    /**
-     * Draw a number of the order of the two consecutive nodes within the
-     * parents way
-     */
-    protected void drawOrderNumber(Node n1, Node n2, int orderNumber) {
-        Point p1 = nc.getPoint(n1);
-        Point p2 = nc.getPoint(n2);
-        painter.drawOrderNumber(p1, p2, orderNumber);
-    }
-
     public void putError(OsmPrimitive p, String text, boolean isError)
     {
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 2675)
@@ -13,4 +13,5 @@
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
@@ -23,4 +24,5 @@
 import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.LanguageInfo;
 
 public class MapPainter {
@@ -30,5 +32,8 @@
     private final NavigatableComponent nc;
     private final boolean inactive;
+
     private final boolean useStrokes;
+    private final boolean showNames;
+    private final boolean showIcons;
 
     private final Color inactiveColor;
@@ -45,10 +50,16 @@
     private final int segmentNumberSpace;
 
-
-    public MapPainter(Graphics2D g, boolean inactive, NavigatableComponent nc, boolean useStrokes, boolean virtual) {
+    private final double circum;
+
+    private final Collection<String> regionalNameOrder;
+
+
+    public MapPainter(MapPaintSettings settings, Graphics2D g, boolean inactive, NavigatableComponent nc, boolean virtual, double dist, double circum) {
         this.g = g;
         this.inactive = inactive;
         this.nc = nc;
-        this.useStrokes = useStrokes;
+        this.useStrokes = settings.getUseStrokesDistance() > dist;
+        this.showNames = settings.getShowNamesDistance() > dist;
+        this.showIcons = settings.getShowIconsDistance() > dist;
 
         this.inactiveColor = PaintColors.INACTIVE.get();
@@ -64,4 +75,8 @@
         this.virtualNodeSpace = Main.pref.getInteger("mappaint.node.virtual-space", 70);
         this.segmentNumberSpace = Main.pref.getInteger("mappaint.segmentnumber.space", 40);
+
+        String[] names = {"name:" + LanguageInfo.getJOSMLocaleCode(), "name", "int_name", "ref", "operator", "brand", "addr:housenumber"};
+        this.regionalNameOrder = Main.pref.getCollection("mappaint.nameOrder", Arrays.asList(names));
+        this.circum = circum;
     }
 
@@ -137,5 +152,5 @@
 
 
-    protected void drawNodeIcon(Node n, ImageIcon icon, boolean annotate, boolean selected, String name) {
+    public void drawNodeIcon(Node n, ImageIcon icon, boolean annotate, boolean selected, String name) {
         Point p = nc.getPoint(n);
         if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth()) || (p.y > nc.getHeight())) return;
@@ -168,6 +183,7 @@
      * @param color The color of the node.
      */
-    public void drawNode(Node n, Color color, int size, int radius, boolean fill, String name) {
+    public void drawNode(Node n, Color color, int size, boolean fill, String name) {
         if (size > 1) {
+            int radius = size / 2;
             Point p = nc.getPoint(n);
             if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth())
@@ -305,4 +321,14 @@
 
     /**
+     * Draw a number of the order of the two consecutive nodes within the
+     * parents way
+     */
+    public void drawOrderNumber(Node n1, Node n2, int orderNumber) {
+        Point p1 = nc.getPoint(n1);
+        Point p2 = nc.getPoint(n2);
+        drawOrderNumber(p1, p2, orderNumber);
+    }
+
+    /**
      * Draw an number of the order of the two consecutive nodes within the
      * parents way
@@ -328,3 +354,47 @@
     }
 
+    //TODO Not a good place for this method
+    public String getNodeName(Node n) {
+        String name = null;
+        if (n.hasKeys()) {
+            for (String rn : regionalNameOrder) {
+                name = n.get(rn);
+                if (name != null) {
+                    break;
+                }
+            }
+        }
+        return name;
+    }
+
+    //TODO Not a good place for this method
+    public String getWayName(Way w) {
+        String name = null;
+        if (w.hasKeys()) {
+            for (String rn : regionalNameOrder) {
+                name = w.get(rn);
+                if (name != null) {
+                    break;
+                }
+            }
+        }
+        return name;
+    }
+
+    public boolean isInactive() {
+        return inactive;
+    }
+
+    public boolean isShowNames() {
+        return showNames;
+    }
+
+    public double getCircum() {
+        return circum;
+    }
+
+    public boolean isShowIcons() {
+        return showIcons;
+    }
+
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/PaintColors.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/PaintColors.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/PaintColors.java	(revision 2675)
@@ -48,3 +48,9 @@
         return Main.pref.getColor(this);
     }
+
+    public static void getColors() {
+        for (PaintColors c:values()) {
+            c.get();
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java	(revision 2675)
@@ -1,4 +1,8 @@
 package org.openstreetmap.josm.gui.mappaint;
 import java.awt.Color;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
 
 public class AreaElemStyle extends ElemStyle
@@ -6,5 +10,5 @@
     public Color color;
     public boolean closed;
-    public LineElemStyle line = null;
+    private LineElemStyle line;
 
     public AreaElemStyle (AreaElemStyle a, long maxScale, long minScale) {
@@ -15,4 +19,6 @@
         this.minScale = minScale;
         this.rules = a.rules;
+        this.line = new LineElemStyle();
+        this.line.color = a.color;
     }
 
@@ -36,3 +42,16 @@
         priority = 0;
     }
+
+    public ElemStyle getLineStyle() {
+        return line;
+    }
+
+    @Override
+    public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, MapPainter painter, boolean selected) {
+        // TODO
+        /*Way way = (Way)primitive;
+        String name = painter.isShowNames() ? painter.getWayName(way) : null;
+        painter.drawArea(getPolygon(way), selected ? paintSettings.getSelectedColor() : color, name);
+        line.paintPrimitive(way, paintSettings, painter, selected);*/
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java	(revision 2675)
@@ -5,7 +5,8 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmUtils;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
 
-abstract public class ElemStyle
-{
+abstract public class ElemStyle {
     // zoom range to display the feature
     public long minScale;
@@ -16,8 +17,14 @@
     Collection<Rule> rules = null;
 
-    public Boolean equals(ElemStyle s)
-    {
-        return s != null && s.getCode().equals(getCode());
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof ElemStyle) && (((ElemStyle) o).getCode().equals(getCode()));
     }
+
+    @Override
+    public int hashCode() {
+        return getClass().hashCode();
+    }
+
     public String getCode()
     {
@@ -25,6 +32,7 @@
         {
             code = "";
-            for(Rule r: rules)
+            for(Rule r: rules) {
                 code += r.toCode();
+            }
         }
         return code;
@@ -39,8 +47,10 @@
             String bv = OsmUtils.getNamedOsmBoolean(r.boolValue);
             if(k == null || (r.value != null && !k.equals(r.value))
-            || (bv != null && !bv.equals(OsmUtils.getNamedOsmBoolean(k))))
+                    || (bv != null && !bv.equals(OsmUtils.getNamedOsmBoolean(k))))
                 return false;
         }
         return true;
     }
+
+    public abstract void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, MapPainter painter, boolean selected);
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyleHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyleHandler.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyleHandler.java	(revision 2675)
@@ -84,18 +84,18 @@
                 if(val.startsWith("+"))
                 {
-                    line.width = Integer.parseInt(val.substring(1));
+                    line.setWidth(Integer.parseInt(val.substring(1)));
                     line.widthMode = LineElemStyle.WidthMode.OFFSET;
                 }
                 else if(val.startsWith("-"))
                 {
-                    line.width = Integer.parseInt(val);
+                    line.setWidth(Integer.parseInt(val));
                     line.widthMode = LineElemStyle.WidthMode.OFFSET;
                 }
                 else if(val.endsWith("%"))
                 {
-                    line.width = Integer.parseInt(val.substring(0, val.length()-1));
+                    line.setWidth(Integer.parseInt(val.substring(0, val.length()-1)));
                     line.widthMode = LineElemStyle.WidthMode.PERCENT;
                 } else {
-                    line.width = Integer.parseInt(val);
+                    line.setWidth(Integer.parseInt(val));
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/IconElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/IconElemStyle.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/IconElemStyle.java	(revision 2675)
@@ -3,4 +3,9 @@
 import javax.swing.GrayFilter;
 import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
 
 public class IconElemStyle extends ElemStyle
@@ -33,3 +38,15 @@
         return disabledIcon = new ImageIcon(GrayFilter.createDisabledImage(icon.getImage()));
     }
+    @Override
+    public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings settings, MapPainter painter, boolean selected) {
+        if (painter.isShowIcons()) {
+            Node n = (Node) primitive;
+            String name = painter.isShowNames()?painter.getNodeName(n):null;
+            painter.drawNodeIcon(n, (painter.isInactive() || n.isDisabled())?getDisabledIcon():icon,
+                    annotate, selected, name);
+        } else {
+            SimpleNodeElemStyle.INSTANCE.paintPrimitive(primitive, settings, painter, selected);
+        }
+
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 2675)
@@ -4,9 +4,22 @@
 import java.util.Collection;
 
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
+import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
 import org.openstreetmap.josm.tools.I18n;
 
-public class LineElemStyle extends ElemStyle implements Comparable<LineElemStyle>
-{
-    public int width;
+public class LineElemStyle extends ElemStyle implements Comparable<LineElemStyle> {
+
+    public static final LineElemStyle UNTAGGED_WAY;
+
+    static {
+        UNTAGGED_WAY = new LineElemStyle();
+        UNTAGGED_WAY.color = PaintColors.UNTAGGED.get();
+    }
+
+    private int width;
     public int realWidth; //the real width of this line in meter
     public Color color;
@@ -60,5 +73,5 @@
     public void init()
     {
-        width = 1;
+        width = -1;
         realWidth = 0;
         dashed = new float[0];
@@ -124,3 +137,95 @@
         }
     }
+
+    @Override
+    public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, MapPainter painter, boolean selected) {
+        Way w = (Way)primitive;
+        /* show direction arrows, if draw.segment.relevant_directions_only is not set,
+        the way is tagged with a direction key
+        (even if the tag is negated as in oneway=false) or the way is selected */
+        boolean showDirection = selected || ((!paintSettings.isUseRealWidth()) && (paintSettings.isShowDirectionArrow()
+                && (!paintSettings.isShowRelevantDirectionsOnly() || w.hasDirectionKeys())));
+        /* head only takes over control if the option is true,
+        the direction should be shown at all and not only because it's selected */
+        boolean showOnlyHeadArrowOnly = showDirection && selected && paintSettings.isShowHeadArrowOnly();
+        Node lastN;
+
+        Color myColor = color;
+        int myWidth = getWidth();
+
+        if (realWidth > 0 && paintSettings.isUseRealWidth() && !showDirection) {
+
+            /* if we have a "width" tag, try use it */
+            /* (this might be slow and could be improved by caching the value in the Way, on the other hand only used if "real width" is enabled) */
+            String widthTag = w.get("width");
+            if(widthTag == null) {
+                widthTag = w.get("est_width");
+            }
+            if(widthTag != null) {
+                try {
+                    realWidth = Integer.parseInt(widthTag);
+                }
+                catch(NumberFormatException nfe) {
+                }
+            }
+
+            myWidth = (int) (100 /  (float) (painter.getCircum() / realWidth));
+            if (myWidth < getWidth()) {
+                myWidth = getWidth();
+            }
+        }
+
+        if(w.highlighted) {
+            myColor = paintSettings.getHighlightColor();
+        } else if (selected) {
+            myColor = paintSettings.getSelectedColor();
+        } else if(w.isDisabled()) {
+            myColor = paintSettings.getInactiveColor();
+        }
+
+        /* draw overlays under the way */
+        if(overlays != null) {
+            for(LineElemStyle s : overlays) {
+                if(!s.over) {
+                    painter.drawWay(w, s.color != null && selected ? myColor: s.color, s.getWidth(myWidth),
+                            s.getDashed(), s.dashedColor, false, false);
+                }
+            }
+        }
+
+        /* draw the way */
+        painter.drawWay(w, myColor, myWidth, dashed, dashedColor, showDirection, showOnlyHeadArrowOnly);
+
+        /* draw overlays above the way */
+        if(overlays != null)  {
+            for(LineElemStyle s : overlays) {
+                if(s.over) {
+                    painter.drawWay(w, s.color != null && selected ? myColor : s.color, s.getWidth(myWidth),
+                            s.getDashed(), s.dashedColor, false, false);
+                }
+            }
+        }
+
+        if(paintSettings.isShowOrderNumber()) {
+            int orderNumber = 0;
+            lastN = null;
+            for(Node n : w.getNodes()) {
+                if(lastN != null) {
+                    orderNumber++;
+                    painter.drawOrderNumber(lastN, n, orderNumber);
+                }
+                lastN = n;
+            }
+        }
+    }
+
+    public int getWidth() {
+        if (width == -1)
+            return MapPaintSettings.INSTANCE.getDefaultSegmentWidth();
+        return width;
+    }
+
+    public void setWidth(int width) {
+        this.width = width;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/NoPaintElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/NoPaintElemStyle.java	(revision 2675)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/NoPaintElemStyle.java	(revision 2675)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
+
+public class NoPaintElemStyle extends ElemStyle {
+
+    public static final NoPaintElemStyle INSTANCE = new NoPaintElemStyle();
+
+    private NoPaintElemStyle() {
+
+    }
+
+    @Override
+    public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, MapPainter painter, boolean selected) {
+        // Do nothing
+    }
+
+}
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/SimpleNodeElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/SimpleNodeElemStyle.java	(revision 2675)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/SimpleNodeElemStyle.java	(revision 2675)
@@ -0,0 +1,36 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint;
+
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
+import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
+
+public class SimpleNodeElemStyle extends ElemStyle {
+
+    public static final SimpleNodeElemStyle INSTANCE = new SimpleNodeElemStyle();
+
+    private SimpleNodeElemStyle() {
+        minScale = 0;
+        maxScale = 1500;
+    }
+
+    @Override
+    public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings settings, MapPainter painter,
+            boolean selected) {
+        Node n = (Node)primitive;
+        String name = painter.isShowNames()?painter.getNodeName(n):null;
+        if (n.highlighted) {
+            painter.drawNode(n, settings.getHighlightColor(), settings.getSelectedNodeSize(), settings.isFillSelectedNode(), name);
+        } else if (selected) {
+            painter.drawNode(n, settings.getSelectedColor(), settings.getSelectedNodeSize(), settings.isFillSelectedNode(), name);
+        } else if (n.isTagged()) {
+            painter.drawNode(n, settings.getNodeColor(), settings.getTaggedNodeSize(), settings.isFillUnselectedNode(), name);
+        } else if (painter.isInactive() || n.isDisabled()) {
+            painter.drawNode(n, settings.getInactiveColor(), settings.getUnselectedNodeSize(), settings.isFillUnselectedNode(), name);
+        } else {
+            painter.drawNode(n, settings.getNodeColor(), settings.getUnselectedNodeSize(), settings.isFillUnselectedNode(), name);
+        }
+    }
+
+}
Index: trunk/src/org/openstreetmap/josm/gui/preferences/ColorPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/ColorPreference.java	(revision 2673)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/ColorPreference.java	(revision 2675)
@@ -34,5 +34,5 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintVisitor;
+import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
 import org.openstreetmap.josm.gui.MapScaler;
 import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
@@ -254,5 +254,5 @@
      */
     private void fixColorPrefixes() {
-        (new MapPaintVisitor()).getColors();
+        PaintColors.getColors();
         MarkerLayer.getColor(null);
         MapScaler.getColor();
