Index: /trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 10875)
@@ -52,5 +52,4 @@
 import org.openstreetmap.josm.data.osm.WaySegment;
 import org.openstreetmap.josm.data.osm.visitor.paint.ArrowPaintHelper;
-import org.openstreetmap.josm.data.osm.visitor.paint.MapPath2D;
 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
 import org.openstreetmap.josm.data.preferences.AbstractToStringProperty;
@@ -66,4 +65,7 @@
 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
 import org.openstreetmap.josm.gui.NavigatableComponent;
+import org.openstreetmap.josm.gui.draw.MapPath2D;
+import org.openstreetmap.josm.gui.draw.MapViewPath;
+import org.openstreetmap.josm.gui.draw.SymbolShape;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
@@ -1509,5 +1511,5 @@
                 g2.setStroke(HELPER_STROKE.get());
 
-                MapPath2D b = new MapPath2D();
+                MapViewPath b = new MapViewPath(mv);
                 b.moveTo(p2);
                 if (absoluteFix) {
@@ -1521,7 +1523,7 @@
                 g2.setColor(SNAP_HELPER_COLOR.get());
                 g2.setStroke(HELPER_STROKE.get());
-                MapPath2D b = new MapPath2D();
+                MapViewPath b = new MapViewPath(mv);
                 b.moveTo(p3);
-                b.lineTo(mv.getPointFor(projectionSource));
+                b.lineTo(projectionSource);
                 g2.draw(b);
             }
@@ -1530,7 +1532,7 @@
                 g2.setColor(HIGHLIGHT_COLOR.get());
                 g2.setStroke(HIGHLIGHT_STROKE.get());
-                MapPath2D b = new MapPath2D();
-                b.moveTo(mv.getPointFor(segmentPoint1));
-                b.lineTo(mv.getPointFor(segmentPoint2));
+                MapViewPath b = new MapViewPath(mv);
+                b.moveTo(segmentPoint1);
+                b.lineTo(segmentPoint2);
                 g2.draw(b);
             }
@@ -1538,5 +1540,5 @@
             g2.setColor(RUBBER_LINE_COLOR.get());
             g2.setStroke(RUBBER_LINE_STROKE.get());
-            MapPath2D b = new MapPath2D();
+            MapViewPath b = new MapViewPath(mv);
             b.moveTo(p1);
             b.lineTo(p3);
@@ -1546,5 +1548,5 @@
             if (SHOW_PROJECTED_POINT.get()) {
                 g2.setStroke(RUBBER_LINE_STROKE.get());
-                g2.drawOval((int) p3.getInViewX()-5, (int) p3.getInViewY()-5, 10, 10); // projected point
+                g2.draw(new MapViewPath(mv).shapeAround(p3, SymbolShape.CIRCLE, 10)); // projected point
             }
 
@@ -1554,5 +1556,5 @@
 
         /**
-         *  If mouse position is close to line at 15-30-45-... angle, remembers this direction
+         * If mouse position is close to line at 15-30-45-... angle, remembers this direction
          * @param currentEN Current position
          * @param baseHeading The heading
Index: /trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 10875)
@@ -48,4 +48,6 @@
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.draw.MapViewPath;
+import org.openstreetmap.josm.gui.draw.SymbolShape;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
@@ -1019,8 +1021,8 @@
             if (newN1en != null) {
 
-                Point p1 = mv.getPoint(initialN1en);
-                Point p2 = mv.getPoint(initialN2en);
-                Point p3 = mv.getPoint(newN1en);
-                Point p4 = mv.getPoint(newN2en);
+                EastNorth p1 = initialN1en;
+                EastNorth p2 = initialN2en;
+                EastNorth p3 = newN1en;
+                EastNorth p4 = newN2en;
 
                 Point2D normalUnitVector = activeMoveDirection != null ? getNormalUniVector() : null;
@@ -1030,10 +1032,10 @@
                     g2.setStroke(mainStroke);
                     // Draw rectangle around new area.
-                    GeneralPath b = new GeneralPath();
-                    b.moveTo(p1.x, p1.y);
-                    b.lineTo(p3.x, p3.y);
-                    b.lineTo(p4.x, p4.y);
-                    b.lineTo(p2.x, p2.y);
-                    b.lineTo(p1.x, p1.y);
+                    MapViewPath b = new MapViewPath(mv);
+                    b.moveTo(p1);
+                    b.lineTo(p3);
+                    b.lineTo(p4);
+                    b.lineTo(p2);
+                    b.lineTo(p1);
                     g2.draw(b);
 
@@ -1063,10 +1065,8 @@
                     if (p1.distance(p2) < 3) {
                         g2.setStroke(mainStroke);
-                        g2.drawOval((int) (p1.x-symbolSize/2), (int) (p1.y-symbolSize/2),
-                                (int) (symbolSize), (int) (symbolSize));
+                        g2.draw(new MapViewPath(mv).shapeAround(p1, SymbolShape.CIRCLE, symbolSize));
                     } else {
-                        Line2D oldline = new Line2D.Double(p1, p2);
                         g2.setStroke(oldLineStroke);
-                        g2.draw(oldline);
+                        g2.draw(new MapViewPath(mv).moveTo(p1).lineTo(p2));
                     }
 
@@ -1081,5 +1081,5 @@
                         // Draw a guideline along the normal.
                         Line2D normline;
-                        Point2D centerpoint = new Point2D.Double((p1.getX()+p2.getX())*0.5, (p1.getY()+p2.getY())*0.5);
+                        Point2D centerpoint = mv.getPoint2D(p1.interpolate(p2, .5));
                         normline = createSemiInfiniteLine(centerpoint, normalUnitVector, g2);
                         g2.draw(normline);
@@ -1163,12 +1163,7 @@
      */
     private void drawReferenceSegment(Graphics2D g2, MapView mv, ReferenceSegment seg) {
-        Point p1 = mv.getPoint(seg.p1);
-        Point p2 = mv.getPoint(seg.p2);
-        GeneralPath b = new GeneralPath();
-        b.moveTo(p1.x, p1.y);
-        b.lineTo(p2.x, p2.y);
         g2.setColor(helperColor);
         g2.setStroke(helperStrokeDash);
-        g2.draw(b);
+        g2.draw(new MapViewPath(mv).moveTo(seg.p1).lineTo(seg.p2));
     }
 
Index: /trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java	(revision 10875)
@@ -6,9 +6,9 @@
 import static org.openstreetmap.josm.tools.I18n.trn;
 
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Cursor;
 import java.awt.Graphics2D;
 import java.awt.Point;
-import java.awt.Stroke;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
@@ -35,14 +35,16 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.WaySegment;
-import org.openstreetmap.josm.data.osm.visitor.paint.MapPath2D;
 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
+import org.openstreetmap.josm.data.preferences.CachingProperty;
 import org.openstreetmap.josm.data.preferences.ColorProperty;
+import org.openstreetmap.josm.data.preferences.IntegerProperty;
+import org.openstreetmap.josm.data.preferences.StrokeProperty;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
+import org.openstreetmap.josm.gui.draw.MapViewPath;
+import org.openstreetmap.josm.gui.draw.SymbolShape;
 import org.openstreetmap.josm.gui.layer.AbstractMapViewPaintable;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.util.ModifierListener;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -56,6 +58,6 @@
         SelectionChangedListener, ModifierListener {
 
-    enum State {
-        selecting, improving
+    private enum State {
+        SELECTING, IMPROVING
     }
 
@@ -73,19 +75,26 @@
     private boolean dragging;
 
-    private final Cursor cursorSelect;
-    private final Cursor cursorSelectHover;
-    private final Cursor cursorImprove;
-    private final Cursor cursorImproveAdd;
-    private final Cursor cursorImproveDelete;
-    private final Cursor cursorImproveAddLock;
-    private final Cursor cursorImproveLock;
+    private final Cursor cursorSelect = ImageProvider.getCursor("normal", "mode");
+    private final Cursor cursorSelectHover = ImageProvider.getCursor("hand", "mode");
+    private final Cursor cursorImprove = ImageProvider.getCursor("crosshair", null);
+    private final Cursor cursorImproveAdd = ImageProvider.getCursor("crosshair", "addnode");
+    private final Cursor cursorImproveDelete = ImageProvider.getCursor("crosshair", "delete_node");
+    private final Cursor cursorImproveAddLock = ImageProvider.getCursor("crosshair", "add_node_lock");
+    private final Cursor cursorImproveLock = ImageProvider.getCursor("crosshair", "lock");
 
     private Color guideColor;
-    private transient Stroke selectTargetWayStroke;
-    private transient Stroke moveNodeStroke;
-    private transient Stroke moveNodeIntersectingStroke;
-    private transient Stroke addNodeStroke;
-    private transient Stroke deleteNodeStroke;
-    private int dotSize;
+
+    private static final CachingProperty<BasicStroke> SELECT_TARGET_WAY_STROKE
+            = new StrokeProperty("improvewayaccuracy.stroke.select-target", "2").cached();
+    private static final CachingProperty<BasicStroke> MOVE_NODE_STROKE
+            = new StrokeProperty("improvewayaccuracy.stroke.move-node", "1 6").cached();
+    private static final CachingProperty<BasicStroke> MOVE_NODE_INTERSECTING_STROKE
+            = new StrokeProperty("improvewayaccuracy.stroke.move-node-intersecting", "1 2 6").cached();
+    private static final CachingProperty<BasicStroke> ADD_NODE_STROKE
+            = new StrokeProperty("improvewayaccuracy.stroke.add-node", "1").cached();
+    private static final CachingProperty<BasicStroke> DELETE_NODE_STROKE
+            = new StrokeProperty("improvewayaccuracy.stroke.delete-node", "1").cached();
+    private static final CachingProperty<Integer> DOT_SIZE
+            = new IntegerProperty("improvewayaccuracy.dot-size", 6).cached();
 
     private boolean selectionChangedBlocked;
@@ -111,12 +120,4 @@
                 KeyEvent.VK_W, Shortcut.DIRECT), mapFrame, Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
 
-        cursorSelect = ImageProvider.getCursor("normal", "mode");
-        cursorSelectHover = ImageProvider.getCursor("hand", "mode");
-        cursorImprove = ImageProvider.getCursor("crosshair", null);
-        cursorImproveAdd = ImageProvider.getCursor("crosshair", "addnode");
-        cursorImproveDelete = ImageProvider.getCursor("crosshair", "delete_node");
-        cursorImproveAddLock = ImageProvider.getCursor("crosshair",
-                "add_node_lock");
-        cursorImproveLock = ImageProvider.getCursor("crosshair", "lock");
         readPreferences();
     }
@@ -156,11 +157,4 @@
         if (guideColor == null)
             guideColor = PaintColors.HIGHLIGHT.get();
-
-        selectTargetWayStroke = GuiHelper.getCustomizedStroke(Main.pref.get("improvewayaccuracy.stroke.select-target", "2"));
-        moveNodeStroke = GuiHelper.getCustomizedStroke(Main.pref.get("improvewayaccuracy.stroke.move-node", "1 6"));
-        moveNodeIntersectingStroke = GuiHelper.getCustomizedStroke(Main.pref.get("improvewayaccuracy.stroke.move-node-intersecting", "1 2 6"));
-        addNodeStroke = GuiHelper.getCustomizedStroke(Main.pref.get("improvewayaccuracy.stroke.add-node", "1"));
-        deleteNodeStroke = GuiHelper.getCustomizedStroke(Main.pref.get("improvewayaccuracy.stroke.delete-node", "1"));
-        dotSize = Main.pref.getInteger("improvewayaccuracy.dot-size", 6);
     }
 
@@ -190,5 +184,5 @@
     @Override
     public String getModeHelpText() {
-        if (state == State.selecting) {
+        if (state == State.SELECTING) {
             if (targetWay != null) {
                 return tr("Click on the way to start improving its shape.");
@@ -234,28 +228,15 @@
         g.setColor(guideColor);
 
-        if (state == State.selecting && targetWay != null) {
+        if (state == State.SELECTING && targetWay != null) {
             // Highlighting the targetWay in Selecting state
             // Non-native highlighting is used, because sometimes highlighted
             // segments are covered with others, which is bad.
-            g.setStroke(selectTargetWayStroke);
+            g.setStroke(SELECT_TARGET_WAY_STROKE.get());
 
             List<Node> nodes = targetWay.getNodes();
 
-            MapPath2D b = new MapPath2D();
-            Point p0 = mv.getPoint(nodes.get(0));
-            Point pn;
-            b.moveTo(p0.x, p0.y);
-
-            for (Node n : nodes) {
-                pn = mv.getPoint(n);
-                b.lineTo(pn.x, pn.y);
-            }
-            if (targetWay.isClosed()) {
-                b.lineTo(p0.x, p0.y);
-            }
-
-            g.draw(b);
-
-        } else if (state == State.improving) {
+            g.draw(new MapViewPath(mv).append(nodes, false));
+
+        } else if (state == State.IMPROVING) {
             // Drawing preview lines and highlighting the node
             // that is going to be moved.
@@ -263,18 +244,19 @@
 
             // Finding endpoints
-            Point p1 = null, p2 = null;
+            Node p1 = null;
+            Node p2 = null;
             if (ctrl && candidateSegment != null) {
-                g.setStroke(addNodeStroke);
-                p1 = mv.getPoint(candidateSegment.getFirstNode());
-                p2 = mv.getPoint(candidateSegment.getSecondNode());
+                g.setStroke(ADD_NODE_STROKE.get());
+                p1 = candidateSegment.getFirstNode();
+                p2 = candidateSegment.getSecondNode();
             } else if (!alt && !ctrl && candidateNode != null) {
-                g.setStroke(moveNodeStroke);
+                g.setStroke(MOVE_NODE_STROKE.get());
                 List<Pair<Node, Node>> wpps = targetWay.getNodePairs(false);
                 for (Pair<Node, Node> wpp : wpps) {
                     if (wpp.a == candidateNode) {
-                        p1 = mv.getPoint(wpp.b);
+                        p1 = wpp.b;
                     }
                     if (wpp.b == candidateNode) {
-                        p2 = mv.getPoint(wpp.a);
+                        p2 = wpp.a;
                     }
                     if (p1 != null && p2 != null) {
@@ -283,5 +265,5 @@
                 }
             } else if (alt && !ctrl && candidateNode != null) {
-                g.setStroke(deleteNodeStroke);
+                g.setStroke(DELETE_NODE_STROKE.get());
                 List<Node> nodes = targetWay.getNodes();
                 int index = nodes.indexOf(candidateNode);
@@ -289,9 +271,9 @@
                 // Only draw line if node is not first and/or last
                 if (index != 0 && index != (nodes.size() - 1)) {
-                    p1 = mv.getPoint(nodes.get(index - 1));
-                    p2 = mv.getPoint(nodes.get(index + 1));
+                    p1 = nodes.get(index - 1);
+                    p2 = nodes.get(index + 1);
                 } else if (targetWay.isClosed()) {
-                    p1 = mv.getPoint(targetWay.getNode(1));
-                    p2 = mv.getPoint(targetWay.getNode(nodes.size() - 2));
+                    p1 = targetWay.getNode(1);
+                    p2 = targetWay.getNode(nodes.size() - 2);
                 }
                 // TODO: indicate what part that will be deleted? (for end nodes)
@@ -300,10 +282,10 @@
 
             // Drawing preview lines
-            MapPath2D b = new MapPath2D();
+            MapViewPath b = new MapViewPath(mv);
             if (alt && !ctrl) {
                 // In delete mode
                 if (p1 != null && p2 != null) {
-                    b.moveTo(p1.x, p1.y);
-                    b.lineTo(p2.x, p2.y);
+                    b.moveTo(p1);
+                    b.lineTo(p2);
                 }
             } else {
@@ -311,9 +293,9 @@
                 if (p1 != null) {
                     b.moveTo(mousePos.x, mousePos.y);
-                    b.lineTo(p1.x, p1.y);
+                    b.lineTo(p1);
                 }
                 if (p2 != null) {
                     b.moveTo(mousePos.x, mousePos.y);
-                    b.lineTo(p2.x, p2.y);
+                    b.lineTo(p2);
                 }
             }
@@ -322,6 +304,6 @@
             // Highlighting candidateNode
             if (candidateNode != null) {
-                p1 = mv.getPoint(candidateNode);
-                g.fillRect(p1.x - dotSize/2, p1.y - dotSize/2, dotSize, dotSize);
+                p1 = candidateNode;
+                g.fill(new MapViewPath(mv).shapeAround(p1, SymbolShape.SQUARE, DOT_SIZE.get()));
             }
 
@@ -329,5 +311,5 @@
                 b.reset();
                 drawIntersectingWayHelperLines(mv, b);
-                g.setStroke(moveNodeIntersectingStroke);
+                g.setStroke(MOVE_NODE_INTERSECTING_STROKE.get());
                 g.draw(b);
             }
@@ -336,5 +318,5 @@
     }
 
-    protected void drawIntersectingWayHelperLines(MapView mv, MapPath2D b) {
+    protected void drawIntersectingWayHelperLines(MapView mv, MapViewPath b) {
         for (final OsmPrimitive referrer : candidateNode.getReferrers()) {
             if (!(referrer instanceof Way) || targetWay.equals(referrer)) {
@@ -347,12 +329,10 @@
                 }
                 if (i > 0) {
-                    final MapViewPoint p = mv.getState().getPointFor(nodes.get(i - 1));
                     b.moveTo(mousePos.x, mousePos.y);
-                    b.lineTo(p);
+                    b.lineTo(nodes.get(i - 1));
                 }
                 if (i < nodes.size() - 1) {
-                    final MapViewPoint p = mv.getState().getPointFor(nodes.get(i + 1));
                     b.moveTo(mousePos.x, mousePos.y);
-                    b.lineTo(p);
+                    b.lineTo(nodes.get(i + 1));
                 }
             }
@@ -414,10 +394,10 @@
         mousePos = e.getPoint();
 
-        if (state == State.selecting) {
+        if (state == State.SELECTING) {
             if (targetWay != null) {
                 getLayerManager().getEditDataSet().setSelected(targetWay.getPrimitiveId());
                 updateStateByCurrentSelection();
             }
-        } else if (state == State.improving && mousePos != null) {
+        } else if (state == State.IMPROVING && mousePos != null) {
             // Checking if the new coordinate is outside of the world
             if (mv.getLatLon(mousePos.x, mousePos.y).isOutSideWorld()) {
@@ -553,8 +533,8 @@
         }
 
-        if (state == State.selecting) {
+        if (state == State.SELECTING) {
             mv.setNewCursor(targetWay == null ? cursorSelect
                     : cursorSelectHover, this);
-        } else if (state == State.improving) {
+        } else if (state == State.IMPROVING) {
             if (alt && !ctrl) {
                 mv.setNewCursor(cursorImproveDelete, this);
@@ -578,5 +558,5 @@
      */
     public void updateCursorDependentObjectsIfNeeded() {
-        if (state == State.improving && (shift || dragging)
+        if (state == State.IMPROVING && (shift || dragging)
                 && !(candidateNode == null && candidateSegment == null)) {
             return;
@@ -589,7 +569,7 @@
         }
 
-        if (state == State.selecting) {
+        if (state == State.SELECTING) {
             targetWay = ImproveWayAccuracyHelper.findWay(mv, mousePos);
-        } else if (state == State.improving) {
+        } else if (state == State.IMPROVING) {
             if (ctrl && !alt) {
                 candidateSegment = ImproveWayAccuracyHelper.findCandidateSegment(mv,
@@ -608,5 +588,5 @@
      */
     public void startSelecting() {
-        state = State.selecting;
+        state = State.SELECTING;
 
         targetWay = null;
@@ -622,5 +602,5 @@
      */
     public void startImproving(Way targetWay) {
-        state = State.improving;
+        state = State.IMPROVING;
 
         DataSet ds = getLayerManager().getEditDataSet();
Index: /trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java	(revision 10875)
@@ -33,5 +33,4 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.WaySegment;
-import org.openstreetmap.josm.data.osm.visitor.paint.MapPath2D;
 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
 import org.openstreetmap.josm.data.preferences.AbstractToStringProperty;
@@ -45,4 +44,5 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.gui.draw.MapViewPath;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
@@ -468,14 +468,14 @@
             g.setStroke(REF_LINE_STROKE.get());
             g.setColor(mainColor);
-            MapPath2D line = new MapPath2D();
-            line.moveTo(mv.getState().getPointFor(referenceSegment.getFirstNode()));
-            line.lineTo(mv.getState().getPointFor(referenceSegment.getSecondNode()));
+            MapViewPath line = new MapViewPath(mv);
+            line.moveTo(referenceSegment.getFirstNode());
+            line.lineTo(referenceSegment.getSecondNode());
             g.draw(line);
 
             g.setStroke(HELPER_LINE_STROKE.get());
             g.setColor(mainColor);
-            line = new MapPath2D();
-            line.moveTo(mv.getState().getPointFor(helperLineStart));
-            line.lineTo(mv.getState().getPointFor(helperLineEnd));
+            line = new MapViewPath(mv);
+            line.moveTo(helperLineStart);
+            line.lineTo(helperLineEnd);
             g.draw(line);
         }
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/ArrowPaintHelper.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/ArrowPaintHelper.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/ArrowPaintHelper.java	(revision 10875)
@@ -3,4 +3,5 @@
 
 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
+import org.openstreetmap.josm.gui.draw.MapPath2D;
 import org.openstreetmap.josm.tools.Utils;
 
Index: unk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPath2D.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPath2D.java	(revision 10874)
+++ 	(revision )
@@ -1,36 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.data.osm.visitor.paint;
-
-import java.awt.geom.Path2D;
-
-import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
-
-/**
- * An extension of {@link Path2D} with special methods for map positions.
- * @author Michael Zangl
- * @since 10827
- */
-public class MapPath2D extends Path2D.Double {
-    /**
-     * Create a new, empty path.
-     */
-    public MapPath2D() {
-        // no default definitions
-    }
-
-    /**
-     * Move the path to the view position of given point
-     * @param p The point
-     */
-    public void moveTo(MapViewPoint p) {
-        moveTo(p.getInViewX(), p.getInViewY());
-    }
-
-    /**
-     * Draw a line to the view position of given point
-     * @param p The point
-     */
-    public void lineTo(MapViewPoint p) {
-        lineTo(p.getInViewX(), p.getInViewY());
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 10875)
@@ -21,5 +21,4 @@
 import java.awt.font.TextLayout;
 import java.awt.geom.AffineTransform;
-import java.awt.geom.GeneralPath;
 import java.awt.geom.Path2D;
 import java.awt.geom.Point2D;
@@ -63,4 +62,6 @@
 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
 import org.openstreetmap.josm.gui.NavigatableComponent;
+import org.openstreetmap.josm.gui.draw.MapPath2D;
+import org.openstreetmap.josm.gui.draw.MapViewPath;
 import org.openstreetmap.josm.gui.mappaint.ElemStyles;
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
@@ -1392,5 +1393,5 @@
         // only highlight the segment if the way itself is not highlighted
         if (!way.isHighlighted() && highlightWaySegments != null) {
-            GeneralPath highlightSegs = null;
+            MapViewPath highlightSegs = null;
             for (WaySegment ws : highlightWaySegments) {
                 if (ws.way != way || ws.lowerIndex < offset) {
@@ -1398,11 +1399,9 @@
                 }
                 if (highlightSegs == null) {
-                    highlightSegs = new GeneralPath();
-                }
-
-                Point2D p1 = mapState.getPointFor(ws.getFirstNode()).getInView();
-                Point2D p2 = mapState.getPointFor(ws.getSecondNode()).getInView();
-                highlightSegs.moveTo(p1.getX(), p1.getY());
-                highlightSegs.lineTo(p2.getX(), p2.getY());
+                    highlightSegs = new MapViewPath(mapState);
+                }
+
+                highlightSegs.moveTo(ws.getFirstNode());
+                highlightSegs.lineTo(ws.getSecondNode());
             }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/WireframeMapRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/WireframeMapRenderer.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/WireframeMapRenderer.java	(revision 10875)
@@ -30,4 +30,5 @@
 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
 import org.openstreetmap.josm.gui.NavigatableComponent;
+import org.openstreetmap.josm.gui.draw.MapPath2D;
 
 /**
Index: /trunk/src/org/openstreetmap/josm/gui/MapViewState.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 10875)
@@ -10,4 +10,5 @@
 import java.awt.geom.Point2D.Double;
 import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
 
 import javax.swing.JComponent;
@@ -29,5 +30,7 @@
  * @since 10343
  */
-public final class MapViewState {
+public final class MapViewState implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     /**
@@ -55,5 +58,5 @@
     public static final int OUTSIDE_RIGHT = 8;
 
-    private final Projecting projecting;
+    private final transient Projecting projecting;
 
     private final int viewWidth;
Index: /trunk/src/org/openstreetmap/josm/gui/draw/MapPath2D.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/draw/MapPath2D.java	(revision 10875)
+++ /trunk/src/org/openstreetmap/josm/gui/draw/MapPath2D.java	(revision 10875)
@@ -0,0 +1,52 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.draw;
+
+import java.awt.geom.Path2D;
+
+import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
+
+/**
+ * An extension of {@link Path2D} with special methods for map positions.
+ * @author Michael Zangl
+ * @since 10875
+ */
+public class MapPath2D extends Path2D.Double {
+    /**
+     * Create a new, empty path.
+     */
+    public MapPath2D() {
+        // no default definitions
+    }
+
+    /**
+     * Move the path to the view position of given point
+     * @param p The point
+     * @return this for easy chaining.
+     */
+    public MapPath2D moveTo(MapViewPoint p) {
+        moveTo(p.getInViewX(), p.getInViewY());
+        return this;
+    }
+
+    /**
+     * Draw a line to the view position of given point
+     * @param p The point
+     * @return this for easy chaining.
+     */
+    public MapPath2D lineTo(MapViewPoint p) {
+        lineTo(p.getInViewX(), p.getInViewY());
+        return this;
+    }
+
+    /**
+     * Add the given shape centered around the given point
+     * @param p The point to draw around
+     * @param symbol The symbol type
+     * @param size The size of the symbol in pixel
+     * @return this for easy chaining.
+     */
+    public MapPath2D shapeAround(MapViewPoint p, SymbolShape symbol, double size) {
+        append(symbol.shapeAround(p.getInViewX(), p.getInViewY(), size), false);
+        return this;
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java	(revision 10875)
+++ /trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java	(revision 10875)
@@ -0,0 +1,157 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.draw;
+
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapViewState;
+import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
+
+/**
+ * This is a version of a java Path2D that allows you to add points to it by simply giving their east/north, lat/lon or node coordinates.
+ * @author Michael Zangl
+ * @since 10875
+ */
+public class MapViewPath extends MapPath2D {
+
+    private final MapViewState state;
+
+    /**
+     * Create a new path
+     * @param mv The map view to use for coordinate conversion.
+     */
+    public MapViewPath(MapView mv) {
+        this(mv.getState());
+    }
+
+    /**
+     * Create a new path
+     * @param state The state to use for coordinate conversion.
+     */
+    public MapViewPath(MapViewState state) {
+        this.state = state;
+    }
+
+    /**
+     * Move the cursor to the given node.
+     * @param n The node
+     * @return this for easy chaining.
+     */
+    public MapViewPath moveTo(Node n) {
+        moveTo(n.getEastNorth());
+        return this;
+    }
+
+    /**
+     * Move the cursor to the given position.
+     * @param eastNorth The position
+     * @return this for easy chaining.
+     */
+    public MapViewPath moveTo(EastNorth eastNorth) {
+        moveTo(state.getPointFor(eastNorth));
+        return this;
+    }
+
+    @Override
+    public MapViewPath moveTo(MapViewPoint p) {
+        super.moveTo(p);
+        return this;
+    }
+
+    /**
+     * Draw a line to the node.
+     * @param n The node
+     * @return this for easy chaining.
+     */
+    public MapViewPath lineTo(Node n) {
+        lineTo(n.getEastNorth());
+        return this;
+    }
+
+    /**
+     * Draw a line to the position.
+     * @param eastNorth The position
+     * @return this for easy chaining.
+     */
+    public MapViewPath lineTo(EastNorth eastNorth) {
+        lineTo(state.getPointFor(eastNorth));
+        return this;
+    }
+
+    @Override
+    public MapViewPath lineTo(MapViewPoint p) {
+        super.lineTo(p);
+        return this;
+    }
+
+    /**
+     * Add the given shape centered around the current node.
+     * @param p1 The point to draw around
+     * @param symbol The symbol type
+     * @param size The size of the symbol in pixel
+     * @return this for easy chaining.
+     */
+    public MapViewPath shapeAround(Node p1, SymbolShape symbol, double size) {
+        shapeAround(p1.getEastNorth(), symbol, size);
+        return this;
+    }
+
+    /**
+     * Add the given shape centered around the current position.
+     * @param eastNorth The point to draw around
+     * @param symbol The symbol type
+     * @param size The size of the symbol in pixel
+     * @return this for easy chaining.
+     */
+    public MapViewPath shapeAround(EastNorth eastNorth, SymbolShape symbol, double size) {
+        shapeAround(state.getPointFor(eastNorth), symbol, size);
+        return this;
+    }
+
+    @Override
+    public MapViewPath shapeAround(MapViewPoint p, SymbolShape symbol, double size) {
+        super.shapeAround(p, symbol, size);
+        return this;
+    }
+
+    /**
+     * Append a list of nodes
+     * @param nodes The nodes to append
+     * @param connect <code>true</code> if we should use a lineTo as first command.
+     * @return this for easy chaining.
+     */
+    public MapViewPath append(Iterable<Node> nodes, boolean connect) {
+        appendWay(nodes, connect, false);
+        return this;
+    }
+
+    /**
+     * Append a list of nodes as closed way.
+     * @param nodes The nodes to append
+     * @param connect <code>true</code> if we should use a lineTo as first command.
+     * @return this for easy chaining.
+     */
+    public MapViewPath appendClosed(Iterable<Node> nodes, boolean connect) {
+        appendWay(nodes, connect, true);
+        return this;
+    }
+
+    private void appendWay(Iterable<Node> nodes, boolean connect, boolean close) {
+        boolean useMoveTo = !connect;
+        Node first = null;
+        for (Node n : nodes) {
+            if (useMoveTo) {
+                moveTo(n);
+            } else {
+                lineTo(n);
+            }
+            if (close && first == null) {
+                first = n;
+            }
+            useMoveTo = false;
+        }
+        if (first != null) {
+            lineTo(first);
+        }
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/draw/SymbolShape.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/draw/SymbolShape.java	(revision 10875)
+++ /trunk/src/org/openstreetmap/josm/gui/draw/SymbolShape.java	(revision 10875)
@@ -0,0 +1,138 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.draw;
+
+import java.awt.Shape;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * A list of possible symbol shapes.
+ * @since 10875
+ */
+public enum SymbolShape {
+    /**
+     * A square
+     */
+    SQUARE("square", 4, Math.PI / 4),
+    /**
+     * A circle
+     */
+    CIRCLE("circle", 1, 0),
+    /**
+     * A triangle with sides of equal lengh
+     */
+    TRIANGLE("triangle", 3, Math.PI / 2),
+    /**
+     * A pentagon
+     */
+    PENTAGON("pentagon", 5, Math.PI / 2),
+    /**
+     * A hexagon
+     */
+    HEXAGON("hexagon", 6, 0),
+    /**
+     * A heptagon
+     */
+    HEPTAGON("heptagon", 7, Math.PI / 2),
+    /**
+     * An octagon
+     */
+    OCTAGON("octagon", 8, Math.PI / 8),
+    /**
+     * a nonagon
+     */
+    NONAGON("nonagon", 9, Math.PI / 2),
+    /**
+     * A decagon
+     */
+    DECAGON("decagon", 10, 0);
+
+    private final String name;
+    final int sides;
+
+    final double rotation;
+
+    SymbolShape(String name, int sides, double rotation) {
+        this.name = name;
+        this.sides = sides;
+        this.rotation = rotation;
+    }
+
+    /**
+     * Create the path for this shape around the given position
+     * @param x The x position
+     * @param y The y position
+     * @param size The size (width for rect, diameter for rest)
+     * @return The symbol.
+     * @since 10875
+     */
+    public Shape shapeAround(double x, double y, double size) {
+        double radius = size / 2;
+        Shape shape;
+        switch (this) {
+        case SQUARE:
+            // optimize for performance reasons
+            shape = new Rectangle2D.Double(x - radius, y - radius, size, size);
+            break;
+        case CIRCLE:
+            shape = new Ellipse2D.Double(x - radius, y - radius, size, size);
+            break;
+        default:
+            shape = buildPolygon(x, y, radius);
+            break;
+        }
+        return shape;
+    }
+
+    private Shape buildPolygon(double cx, double cy, double radius) {
+        GeneralPath polygon = new GeneralPath();
+        for (int i = 0; i < sides; i++) {
+            double angle = ((2 * Math.PI / sides) * i) - rotation;
+            double x = cx + radius * Math.cos(angle);
+            double y = cy + radius * Math.sin(angle);
+            if (i == 0) {
+                polygon.moveTo(x, y);
+            } else {
+                polygon.lineTo(x, y);
+            }
+        }
+        polygon.closePath();
+        return polygon;
+    }
+
+    /**
+     * Gets the number of normally straight sides this symbol has. Returns 1 for a circle.
+     * @return The sides of the symbol
+     */
+    public int getSides() {
+        return sides;
+    }
+
+    /**
+     * Gets the rotation of the first point of this symbol.
+     * @return The rotation
+     */
+    public double getRotation() {
+        return rotation;
+    }
+
+    /**
+     * Get the MapCSS name for this shape
+     * @return The name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the shape with the given name
+     * @param val The name to search
+     * @return The shape as optional
+     */
+    public static Optional<SymbolShape> forName(String val) {
+        return Stream.of(values()).filter(shape -> val.equals(shape.name)).findAny();
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/draw/package-info.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/draw/package-info.java	(revision 10875)
+++ /trunk/src/org/openstreetmap/josm/gui/draw/package-info.java	(revision 10875)
@@ -0,0 +1,6 @@
+// License: GPL. For details, see LICENSE file.
+
+/**
+ * Provides GUI classes for 2D drawing in the map.
+ */
+package org.openstreetmap.josm.gui.draw;
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java	(revision 10875)
@@ -16,4 +16,5 @@
 import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
 import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer;
+import org.openstreetmap.josm.gui.draw.SymbolShape;
 import org.openstreetmap.josm.gui.mappaint.Cascade;
 import org.openstreetmap.josm.gui.mappaint.Environment;
@@ -24,5 +25,4 @@
 import org.openstreetmap.josm.gui.mappaint.styleelement.BoxTextElement.BoxProvider;
 import org.openstreetmap.josm.gui.mappaint.styleelement.BoxTextElement.SimpleBoxProvider;
-import org.openstreetmap.josm.gui.mappaint.styleelement.Symbol.SymbolShape;
 import org.openstreetmap.josm.gui.util.RotationAngle;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/Symbol.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/Symbol.java	(revision 10874)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/Symbol.java	(revision 10875)
@@ -5,10 +5,7 @@
 import java.awt.Shape;
 import java.awt.Stroke;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Rectangle2D;
 import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Stream;
+
+import org.openstreetmap.josm.gui.draw.SymbolShape;
 
 /**
@@ -86,121 +83,5 @@
      */
     public Shape buildShapeAround(double x, double y) {
-        int radius = size / 2;
-        Shape shape;
-        switch (symbolShape) {
-        case SQUARE:
-            // optimize for performance reasons
-            shape = new Rectangle2D.Double(x - radius, y - radius, size, size);
-            break;
-        case CIRCLE:
-            shape = new Ellipse2D.Double(x - radius, y - radius, size, size);
-            break;
-        default:
-            shape = buildPolygon(x, y, radius);
-            break;
-        }
-        return shape;
-    }
-
-    private Shape buildPolygon(double cx, double cy, int radius) {
-        GeneralPath polygon = new GeneralPath();
-        for (int i = 0; i < symbolShape.sides; i++) {
-            double angle = ((2 * Math.PI / symbolShape.sides) * i) - symbolShape.rotation;
-            double x = cx + radius * Math.cos(angle);
-            double y = cy + radius * Math.sin(angle);
-            if (i == 0) {
-                polygon.moveTo(x, y);
-            } else {
-                polygon.lineTo(x, y);
-            }
-        }
-        polygon.closePath();
-        return polygon;
-    }
-
-    /**
-     * A list of possible symbol shapes.
-     */
-    public enum SymbolShape {
-        /**
-         * A square
-         */
-        SQUARE("square", 4, Math.PI / 4),
-        /**
-         * A circle
-         */
-        CIRCLE("circle", 1, 0),
-        /**
-         * A triangle with sides of equal lengh
-         */
-        TRIANGLE("triangle", 3, Math.PI / 2),
-        /**
-         * A pentagon
-         */
-        PENTAGON("pentagon", 5, Math.PI / 2),
-        /**
-         * A hexagon
-         */
-        HEXAGON("hexagon", 6, 0),
-        /**
-         * A heptagon
-         */
-        HEPTAGON("heptagon", 7, Math.PI / 2),
-        /**
-         * An octagon
-         */
-        OCTAGON("octagon", 8, Math.PI / 8),
-        /**
-         * a nonagon
-         */
-        NONAGON("nonagon", 9, Math.PI / 2),
-        /**
-         * A decagon
-         */
-        DECAGON("decagon", 10, 0);
-
-        private final String name;
-        final int sides;
-
-        final double rotation;
-
-        SymbolShape(String name, int sides, double rotation) {
-            this.name = name;
-            this.sides = sides;
-            this.rotation = rotation;
-        }
-
-        /**
-         * Gets the number of normally straight sides this symbol has. Returns 1 for a circle.
-         * @return The sides of the symbol
-         */
-        public int getSides() {
-            return sides;
-        }
-
-        /**
-         * Gets the rotateion of the first point of this symbol.
-         * @return The roration
-         */
-        public double getRotation() {
-            return rotation;
-        }
-
-        /**
-         * Get the MapCSS name for this shape
-         * @return The name
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Get the shape with the given name
-         * @param val The name to search
-         * @return The shape as optional
-         */
-        public static Optional<SymbolShape> forName(String val) {
-            return Stream.of(values()).filter(shape -> val.equals(shape.name)).findAny();
-        }
+        return symbolShape.shapeAround(x, y, size);
     }
 }
