diff --git a/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java b/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
index 35feecd..d4b71ee 100644
--- a/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
+++ b/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
@@ -51,7 +51,6 @@ import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
 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;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
@@ -65,9 +64,12 @@ import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.MapViewState;
 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.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.mappaint.styleelement.Symbol.SymbolShape;
 import org.openstreetmap.josm.gui.util.KeyPressReleaseListener;
 import org.openstreetmap.josm.gui.util.ModifierListener;
 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
@@ -1507,7 +1509,7 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
                 g2.setColor(SNAP_HELPER_COLOR.get());
                 g2.setStroke(HELPER_STROKE.get());
 
-                MapPath2D b = new MapPath2D();
+                MapViewPath b = new MapViewPath(mv);
                 b.moveTo(p2);
                 if (absoluteFix) {
                     b.lineTo(p2.interpolate(p1, 2)); // bi-directional line
@@ -1519,24 +1521,24 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
             if (projectionSource != null) {
                 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);
             }
 
             if (customBaseHeading >= 0) {
                 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);
             }
 
             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);
             g2.draw(b);
@@ -1544,7 +1546,7 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
             g2.drawString(labelText, (int) p3.getInViewX()-5, (int) p3.getInViewY()+20);
             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
             }
 
             g2.setColor(SNAP_HELPER_COLOR.get());
@@ -1552,7 +1554,7 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
         }
 
         /**
-         *  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
          * @param curHeading The current mouse heading
diff --git a/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java b/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
index e95966b..ca1ede9 100644
--- a/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
+++ b/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
@@ -47,9 +47,11 @@ import org.openstreetmap.josm.data.preferences.ColorProperty;
 import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.draw.MapViewPath;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.mappaint.styleelement.Symbol.SymbolShape;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.util.KeyPressReleaseListener;
 import org.openstreetmap.josm.gui.util.ModifierListener;
@@ -1018,10 +1020,10 @@ public class ExtrudeAction extends MapMode implements MapViewPaintable, KeyPress
         } else {
             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;
 
@@ -1029,12 +1031,12 @@ public class ExtrudeAction extends MapMode implements MapViewPaintable, KeyPress
                     g2.setColor(mainColor);
                     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.getState());
+                    b.moveTo(p1);
+                    b.lineTo(p3);
+                    b.lineTo(p4);
+                    b.lineTo(p2);
+                    b.lineTo(p1);
                     g2.draw(b);
 
                     if (dualAlignActive) {
@@ -1062,12 +1064,10 @@ public class ExtrudeAction extends MapMode implements MapViewPaintable, KeyPress
                     g2.setColor(mainColor);
                     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.getState()).shapeAround(p1, SymbolShape.CIRCLE, symbolSize));
                     } else {
-                        Line2D oldline = new Line2D.Double(p1, p2);
                         g2.setStroke(oldLineStroke);
-                        g2.draw(oldline);
+                        g2.draw(new MapViewPath(mv.getState()).moveTo(p1).lineTo(p2));
                     }
 
                     if (dualAlignActive) {
@@ -1080,7 +1080,7 @@ public class ExtrudeAction extends MapMode implements MapViewPaintable, KeyPress
                         g2.setStroke(helperStrokeDash);
                         // 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);
                         // Draw right angle marker on initial position, only when moving at right angle
@@ -1162,13 +1162,12 @@ public class ExtrudeAction extends MapMode implements MapViewPaintable, KeyPress
      * @param seg the reference segment
      */
     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);
+
+        MapViewPath b = new MapViewPath(mv.getState());
+        b.moveTo(seg.p1);
+        b.lineTo(seg.p2);
         g2.draw(b);
     }
 
diff --git a/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java b/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java
index e09b698..dcf867b 100644
--- a/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java
+++ b/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java
@@ -5,11 +5,11 @@ import static org.openstreetmap.josm.tools.I18n.marktr;
 import static org.openstreetmap.josm.tools.I18n.tr;
 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;
 import java.util.ArrayList;
@@ -34,16 +34,18 @@ 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.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.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.mappaint.styleelement.Symbol.SymbolShape;
 import org.openstreetmap.josm.gui.util.ModifierListener;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Pair;
@@ -55,8 +57,8 @@ import org.openstreetmap.josm.tools.Shortcut;
 public class ImproveWayAccuracyAction extends MapMode implements
         SelectionChangedListener, ModifierListener {
 
-    enum State {
-        selecting, improving
+    private enum State {
+        SELECTING, IMPROVING
     }
 
     private State state;
@@ -72,21 +74,28 @@ public class ImproveWayAccuracyAction extends MapMode implements
     private Point mousePos;
     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;
 
@@ -110,14 +119,6 @@ public class ImproveWayAccuracyAction extends MapMode implements
                 tr("Mode: {0}", tr("Improve Way Accuracy")),
                 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,12 +157,6 @@ public class ImproveWayAccuracyAction extends MapMode implements
         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);
     }
 
     @Override
@@ -189,7 +184,7 @@ public class ImproveWayAccuracyAction extends MapMode implements
 
     @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.");
             } else {
@@ -233,109 +228,97 @@ public class ImproveWayAccuracyAction extends MapMode implements
 
         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);
+            g.draw(new MapViewPath(mv.getState()).append(nodes, false));
 
-        } else if (state == State.improving) {
+        } else if (state == State.IMPROVING) {
             // Drawing preview lines and highlighting the node
             // that is going to be moved.
             // Non-native highlighting is used here as well.
 
             // 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) {
                         break;
                     }
                 }
             } 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);
 
                 // 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)
             }
 
 
             // Drawing preview lines
-            MapPath2D b = new MapPath2D();
+            MapViewPath b = new MapViewPath(mv.getState());
             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 {
                 // In add or move mode
                 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);
                 }
             }
             g.draw(b);
 
             // 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.getState()).shapeAround(p1, SymbolShape.SQUARE, DOT_SIZE.get()));
             }
 
             if (!alt && !ctrl && candidateNode != null) {
                 b.reset();
                 drawIntersectingWayHelperLines(mv, b);
-                g.setStroke(moveNodeIntersectingStroke);
+                g.setStroke(MOVE_NODE_INTERSECTING_STROKE.get());
                 g.draw(b);
             }
 
         }
     }
 
-    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)) {
                 continue;
@@ -346,14 +329,12 @@ public class ImproveWayAccuracyAction extends MapMode implements
                     continue;
                 }
                 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));
                 }
             }
         }
@@ -413,12 +394,12 @@ public class ImproveWayAccuracyAction extends MapMode implements
         updateKeyModifiers(e);
         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()) {
                 JOptionPane.showMessageDialog(Main.parent,
@@ -552,10 +533,10 @@ public class ImproveWayAccuracyAction extends MapMode implements
             return;
         }
 
-        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);
             } else if (shift || dragging) {
@@ -577,7 +558,7 @@ public class ImproveWayAccuracyAction extends MapMode implements
      * candidateSegment
      */
     public void updateCursorDependentObjectsIfNeeded() {
-        if (state == State.improving && (shift || dragging)
+        if (state == State.IMPROVING && (shift || dragging)
                 && !(candidateNode == null && candidateSegment == null)) {
             return;
         }
@@ -588,9 +569,9 @@ public class ImproveWayAccuracyAction extends MapMode implements
             return;
         }
 
-        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,
                         targetWay, mousePos);
@@ -607,7 +588,7 @@ public class ImproveWayAccuracyAction extends MapMode implements
      * Switches to Selecting state
      */
     public void startSelecting() {
-        state = State.selecting;
+        state = State.SELECTING;
 
         targetWay = null;
 
@@ -621,7 +602,7 @@ public class ImproveWayAccuracyAction extends MapMode implements
      * @param targetWay Way that is going to be improved
      */
     public void startImproving(Way targetWay) {
-        state = State.improving;
+        state = State.IMPROVING;
 
         DataSet ds = getLayerManager().getEditDataSet();
         Collection<OsmPrimitive> currentSelection = ds.getSelected();
diff --git a/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java b/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java
index 16f985f..277d631 100644
--- a/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java
+++ b/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java
@@ -32,7 +32,6 @@ 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.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;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
@@ -44,6 +43,7 @@ import org.openstreetmap.josm.data.preferences.StrokeProperty;
 import org.openstreetmap.josm.gui.MapFrame;
 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;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
@@ -467,16 +467,16 @@ public class ParallelWayAction extends MapMode implements ModifierListener, MapV
             // FIXME: should clip the line (gets insanely slow when zoomed in on a very long line
             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.getState());
+            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.getState());
+            line.moveTo(helperLineStart);
+            line.lineTo(helperLineEnd);
             g.draw(line);
         }
     }
diff --git a/src/org/openstreetmap/josm/data/osm/visitor/paint/ArrowPaintHelper.java b/src/org/openstreetmap/josm/data/osm/visitor/paint/ArrowPaintHelper.java
index bdfa09d..7f99f0f 100644
--- a/src/org/openstreetmap/josm/data/osm/visitor/paint/ArrowPaintHelper.java
+++ b/src/org/openstreetmap/josm/data/osm/visitor/paint/ArrowPaintHelper.java
@@ -2,6 +2,7 @@
 package org.openstreetmap.josm.data.osm.visitor.paint;
 
 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
+import org.openstreetmap.josm.gui.draw.MapPath2D;
 import org.openstreetmap.josm.tools.Utils;
 
 /**
diff --git a/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPath2D.java b/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPath2D.java
deleted file mode 100644
index cf2593c..0000000
--- a/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPath2D.java
+++ /dev/null
@@ -1,36 +0,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());
-    }
-}
diff --git a/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java b/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
index 3b99149..aa7875b 100644
--- a/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
+++ b/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
@@ -20,7 +20,6 @@ import java.awt.font.GlyphVector;
 import java.awt.font.LineMetrics;
 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;
 import java.awt.geom.Rectangle2D;
@@ -62,6 +61,8 @@ import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.Poly
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;
 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;
 import org.openstreetmap.josm.gui.mappaint.StyleElementList;
@@ -1391,19 +1392,17 @@ public class StyledMapRenderer extends AbstractMapRenderer {
 
         // 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) {
                     continue;
                 }
                 if (highlightSegs == null) {
-                    highlightSegs = new GeneralPath();
+                    highlightSegs = new MapViewPath(mapState);
                 }
 
-                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.moveTo(ws.getFirstNode());
+                highlightSegs.lineTo(ws.getSecondNode());
             }
 
             drawPathHighlight(highlightSegs, line);
diff --git a/src/org/openstreetmap/josm/data/osm/visitor/paint/WireframeMapRenderer.java b/src/org/openstreetmap/josm/data/osm/visitor/paint/WireframeMapRenderer.java
index 4867897..6971d87 100644
--- a/src/org/openstreetmap/josm/data/osm/visitor/paint/WireframeMapRenderer.java
+++ b/src/org/openstreetmap/josm/data/osm/visitor/paint/WireframeMapRenderer.java
@@ -29,6 +29,7 @@ import org.openstreetmap.josm.data.osm.WaySegment;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
 import org.openstreetmap.josm.gui.NavigatableComponent;
+import org.openstreetmap.josm.gui.draw.MapPath2D;
 
 /**
  * A map renderer that paints a simple scheme of every primitive it visits to a
diff --git a/src/org/openstreetmap/josm/gui/MapViewState.java b/src/org/openstreetmap/josm/gui/MapViewState.java
index 9969eb0..e3bbe51 100644
--- a/src/org/openstreetmap/josm/gui/MapViewState.java
+++ b/src/org/openstreetmap/josm/gui/MapViewState.java
@@ -9,6 +9,7 @@ import java.awt.geom.Path2D;
 import java.awt.geom.Point2D;
 import java.awt.geom.Point2D.Double;
 import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
 
 import javax.swing.JComponent;
 
@@ -28,7 +29,9 @@ import org.openstreetmap.josm.tools.bugreport.BugReport;
  * @author Michael Zangl
  * @since 10343
  */
-public final class MapViewState {
+public final class MapViewState implements Serializable {
+
+    private static final long serialVersionUID = 1l;
 
     /**
      * A flag indicating that the point is outside to the top of the map view.
@@ -54,7 +57,7 @@ public final class MapViewState {
      */
     public static final int OUTSIDE_RIGHT = 8;
 
-    private final Projecting projecting;
+    private final transient Projecting projecting;
 
     private final int viewWidth;
     private final int viewHeight;
diff --git a/src/org/openstreetmap/josm/gui/draw/MapPath2D.java b/src/org/openstreetmap/josm/gui/draw/MapPath2D.java
new file mode 100644
index 0000000..4675cce
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/draw/MapPath2D.java
@@ -0,0 +1,53 @@
+// 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;
+import org.openstreetmap.josm.gui.mappaint.styleelement.Symbol.SymbolShape;
+
+/**
+ * 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
+     * @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;
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/draw/MapViewPath.java b/src/org/openstreetmap/josm/gui/draw/MapViewPath.java
new file mode 100644
index 0000000..7b2fb49
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/draw/MapViewPath.java
@@ -0,0 +1,149 @@
+// 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.MapViewState;
+import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
+import org.openstreetmap.josm.gui.mappaint.styleelement.Symbol.SymbolShape;
+
+/**
+ * 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 xxx
+ */
+public class MapViewPath extends MapPath2D {
+
+    private final MapViewState state;
+
+    /**
+     * 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);
+        }
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/mappaint/styleelement/Symbol.java b/src/org/openstreetmap/josm/gui/mappaint/styleelement/Symbol.java
index 6699102..0e70090 100644
--- a/src/org/openstreetmap/josm/gui/mappaint/styleelement/Symbol.java
+++ b/src/org/openstreetmap/josm/gui/mappaint/styleelement/Symbol.java
@@ -85,37 +85,7 @@ public class Symbol {
      * @return The symbol shape.
      */
     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;
+        return symbolShape.shapeAround(x, y, size);
     }
 
     /**
@@ -171,6 +141,47 @@ public class Symbol {
         }
 
         /**
+         * 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.
+         */
+        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
          */
