Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java	(revision 2670)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java	(revision 2671)
@@ -7,6 +7,8 @@
 
 import java.awt.Color;
+import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Polygon;
+import java.awt.Rectangle;
 import java.awt.geom.Point2D;
 import java.util.ArrayList;
@@ -32,4 +34,5 @@
 import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.gui.mappaint.AreaElemStyle;
 import org.openstreetmap.josm.gui.mappaint.ElemStyle;
@@ -40,5 +43,9 @@
 import org.openstreetmap.josm.tools.LanguageInfo;
 
-public class MapPaintVisitor extends SimplePaintVisitor {
+public class MapPaintVisitor implements PaintVisitor {
+
+    protected Graphics2D g;
+    protected NavigatableComponent nc;
+
     protected boolean useRealWidth;
     protected boolean zoomLevelDisplay;
@@ -63,4 +70,26 @@
     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;
+
     protected boolean isZoomOk(ElemStyle e) {
         if (!zoomLevelDisplay) /* show everything if the user wishes so */
@@ -108,12 +137,4 @@
     }
 
-    /**
-     * Draw a small rectangle.
-     * White if selected (as always) or red otherwise.
-     *
-     * @param n The node to draw.
-     */
-    @Override
-    public void visit(Node n) {}
     public void drawNode(Node n) {
         /* check, if the node is visible at all */
@@ -151,10 +172,4 @@
     }
 
-    /**
-     * Draw a line for all segments, according to tags.
-     * @param w The way to draw.
-     */
-    @Override
-    public void visit(Way w) {}
     public void drawWay(Way w, int fillAreas) {
         if(w.getNodesCount() < 2)
@@ -453,6 +468,4 @@
     }
 
-    @Override
-    public void visit(Relation r) {}
     public void paintUnselectedRelation(Relation r) {
 
@@ -982,4 +995,14 @@
     }
 
+    protected boolean isPolygonVisible(Polygon polygon) {
+        Rectangle bounds = polygon.getBounds();
+        if (bounds.width == 0 && bounds.height == 0) return false;
+        if (bounds.x > nc.getWidth()) return false;
+        if (bounds.y > nc.getHeight()) return false;
+        if (bounds.x + bounds.width < 0) return false;
+        if (bounds.y + bounds.height < 0) return false;
+        return true;
+    }
+
     protected Polygon getPolygon(Way w)
     {
@@ -1054,8 +1077,9 @@
     }
 
-    @Override
-    public void getColors()
-    {
-        super.getColors();
+    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();
@@ -1083,5 +1107,4 @@
 
     /* Shows areas before non-areas */
-    @Override
     public void visitAll(DataSet data, boolean virtual, Bounds bounds) {
         BBox bbox = new BBox(bounds);
@@ -1098,5 +1121,20 @@
         dist = ll1.greatCircleDistance(ll2);
 
-        getSettings(virtual);
+        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);
@@ -1111,5 +1149,5 @@
         regionalNameOrder = Main.pref.getCollection("mappaint.nameOrder", Arrays.asList(names));
 
-        this.painter = new MapPainter(g, inactive, nc, useStrokes > dist);
+        this.painter = new MapPainter(g, inactive, nc, useStrokes > dist, virtual);
 
         data.clearErrors();
@@ -1194,5 +1232,5 @@
         }
 
-        drawVirtualNodes(data.searchWays(bbox));
+        painter.drawVirtualNodes(data.searchWays(bbox));
     }
 
@@ -1204,5 +1242,5 @@
         Point p1 = nc.getPoint(n1);
         Point p2 = nc.getPoint(n2);
-        drawOrderNumber(p1, p2, orderNumber);
+        painter.drawOrderNumber(p1, p2, orderNumber);
     }
 
@@ -1211,3 +1249,15 @@
         data.addError(p, isError ? tr("Error: {0}", text) : tr("Warning: {0}", text));
     }
+
+    public void setGraphics(Graphics2D g) {
+        this.g = g;
+    }
+
+    public void setInactive(boolean inactive) {
+        this.inactive = inactive;
+    }
+
+    public void setNavigatableComponent(NavigatableComponent nc) {
+        this.nc = nc;
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 2670)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 2671)
@@ -13,4 +13,5 @@
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Rectangle2D;
+import java.util.Collection;
 import java.util.Iterator;
 
@@ -35,9 +36,15 @@
     private final Color selectedColor;
     private final Color areaTextColor;
-
-    private Font orderFont;
-    private int fillAlpha;
-
-    public MapPainter(Graphics2D g, boolean inactive, NavigatableComponent nc, boolean useStrokes) {
+    private final Color nodeColor;
+    private final Color backgroundColor;
+
+    private final Font orderFont;
+    private final int fillAlpha;
+    private final int virtualNodeSize;
+    private final int virtualNodeSpace;
+    private final int segmentNumberSpace;
+
+
+    public MapPainter(Graphics2D g, boolean inactive, NavigatableComponent nc, boolean useStrokes, boolean virtual) {
         this.g = g;
         this.inactive = inactive;
@@ -49,7 +56,12 @@
         this.selectedColor = PaintColors.SELECTED.get();
         this.areaTextColor = PaintColors.AREA_TEXT.get();
+        this.nodeColor = PaintColors.NODE.get();
+        this.backgroundColor = PaintColors.BACKGROUND.get();
 
         this.orderFont = new Font(Main.pref.get("mappaint.font", "Helvetica"), Font.PLAIN, Main.pref.getInteger("mappaint.fontsize", 8));
         this.fillAlpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fillalpha", 50))));
+        this.virtualNodeSize = virtual ? Main.pref.getInteger("mappaint.node.virtual-size", 8) / 2 : 0;
+        this.virtualNodeSpace = Main.pref.getInteger("mappaint.node.virtual-space", 70);
+        this.segmentNumberSpace = Main.pref.getInteger("mappaint.segmentnumber.space", 40);
     }
 
@@ -247,3 +259,72 @@
     }
 
+    public void drawVirtualNodes(Collection<Way> ways) {
+
+        if (virtualNodeSize != 0) {
+            GeneralPath path = new GeneralPath();
+            for (Way osm: ways){
+                if (osm.isUsable() && !osm.isFiltered()) {
+                    visitVirtual(path, osm);
+                }
+            }
+            g.setColor(nodeColor);
+            g.draw(path);
+        }
+    }
+
+    public void visitVirtual(GeneralPath path, Way w) {
+        Iterator<Node> it = w.getNodes().iterator();
+        if (it.hasNext()) {
+            Point lastP = nc.getPoint(it.next());
+            while(it.hasNext())
+            {
+                Point p = nc.getPoint(it.next());
+                if(isSegmentVisible(lastP, p) && isLargeSegment(lastP, p, virtualNodeSpace))
+                {
+                    int x = (p.x+lastP.x)/2;
+                    int y = (p.y+lastP.y)/2;
+                    path.moveTo(x-virtualNodeSize, y);
+                    path.lineTo(x+virtualNodeSize, y);
+                    path.moveTo(x, y-virtualNodeSize);
+                    path.lineTo(x, y+virtualNodeSize);
+                }
+                lastP = p;
+            }
+        }
+    }
+
+    private static boolean isLargeSegment(Point p1, Point p2, int space)  {
+        int xd = p1.x-p2.x; if(xd < 0) {
+            xd = -xd;
+        }
+        int yd = p1.y-p2.y; if(yd < 0) {
+            yd = -yd;
+        }
+        return (xd+yd > space);
+    }
+
+    /**
+     * Draw an number of the order of the two consecutive nodes within the
+     * parents way
+     */
+    protected void drawOrderNumber(Point p1, Point p2, int orderNumber) {
+        if (isSegmentVisible(p1, p2) && isLargeSegment(p1, p2, segmentNumberSpace)) {
+            String on = Integer.toString(orderNumber);
+            int strlen = on.length();
+            int x = (p1.x+p2.x)/2 - 4*strlen;
+            int y = (p1.y+p2.y)/2 + 4;
+
+            if(virtualNodeSize != 0 && isLargeSegment(p1, p2, virtualNodeSpace))
+            {
+                y = (p1.y+p2.y)/2 - virtualNodeSize - 3;
+            }
+
+            Color c = g.getColor();
+            g.setColor(backgroundColor);
+            g.fillRect(x-1, y-12, 8*strlen+1, 14);
+            g.setColor(c);
+            g.drawString(on, x, y);
+        }
+    }
+
 }
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/PaintVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/PaintVisitor.java	(revision 2671)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/PaintVisitor.java	(revision 2671)
@@ -0,0 +1,15 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.visitor.paint;
+
+import java.awt.Graphics2D;
+
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.NavigatableComponent;
+
+public interface PaintVisitor {
+    void setGraphics(Graphics2D g);
+    void setNavigatableComponent(NavigatableComponent nc);
+    void setInactive(boolean inactive);
+    void visitAll(DataSet data, boolean virtual, Bounds box);
+}
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/SimplePaintVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/SimplePaintVisitor.java	(revision 2670)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/SimplePaintVisitor.java	(revision 2671)
@@ -33,5 +33,5 @@
  * @author imi
  */
-public class SimplePaintVisitor extends AbstractVisitor {
+public class SimplePaintVisitor extends AbstractVisitor implements PaintVisitor {
     /**
      * The environment to paint to.
@@ -487,3 +487,7 @@
         }
     }
+
+    public void setInactive(boolean inactive) {
+        this.inactive = inactive;
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 2670)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 2671)
@@ -60,4 +60,5 @@
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintVisitor;
+import org.openstreetmap.josm.data.osm.visitor.paint.PaintVisitor;
 import org.openstreetmap.josm.data.osm.visitor.paint.SimplePaintVisitor;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
@@ -238,5 +239,5 @@
         }
 
-        SimplePaintVisitor painter;
+        PaintVisitor painter;
         if (Main.pref.getBoolean("draw.wireframe")) {
             painter = new SimplePaintVisitor();
@@ -246,5 +247,5 @@
         painter.setGraphics(g);
         painter.setNavigatableComponent(mv);
-        painter.inactive = inactive;
+        painter.setInactive(inactive);
         painter.visitAll(data, virtual, box);
         Main.map.conflictDialog.paintConflicts(g, mv);
