Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 1312)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 1313)
@@ -223,5 +223,5 @@
                     for (int i : is) segSet.add(
                         Pair.sort(new Pair<Node,Node>(w.nodes.get(i), w.nodes.get(i+1))));
-                    for (int i : is) wnew.nodes.add(i + 1, n);
+                    for (int i : is) wnew.addNode(i + 1, n);
 
                     cmds.add(new ChangeCommand(insertPoint.getKey(), wnew));
@@ -287,5 +287,5 @@
             if(way != null) {
                 int nodeCount=0;
-                for (Node p : way.nodes) 
+                for (Node p : way.nodes)
                     if(p.equals(n0)) nodeCount++;
                 if(nodeCount > 1) way = null;
@@ -294,5 +294,5 @@
             if (way == null) {
                 way = new Way();
-                way.nodes.add(n0);
+                way.addNode(n0);
                 cmds.add(new AddCommand(way));
             } else {
@@ -309,16 +309,15 @@
             // Connected to a node that's already in the way
             if(way != null && way.nodes.contains(n)) {
-                System.out.println("Stop drawing, node is part of current way");
+                //System.out.println("Stop drawing, node is part of current way");
                 wayIsFinished = true;
                 selection.clear();
                 //Main.map.selectMapMode(new SelectAction(Main.map));
             }
-            
+
             // Add new node to way
-            if (way.nodes.get(way.nodes.size() - 1) == n0) {
-                way.nodes.add(n);
-            } else {
-                way.nodes.add(0, n);
-            }
+            if (way.nodes.get(way.nodes.size() - 1) == n0)
+                way.addNode(n);
+            else
+                way.addNode(0, n);
 
             extendedWay = true;
@@ -327,12 +326,11 @@
 
         String title;
-        if (!extendedWay && !newNode) {
-            return; // We didn't do anything.
-        } else if (!extendedWay) {
-            if (reuseWays.isEmpty()) {
+        if (!extendedWay) {
+            if (!newNode)
+              return; // We didn't do anything.
+            else if (reuseWays.isEmpty())
                 title = tr("Add node");
-            } else {
+            else
                 title = tr("Add node into way");
-            }
             for (Way w : reuseWays) w.selected = false;
             Main.ds.setSelected(n);
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 1312)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 1313)
@@ -228,7 +228,7 @@
             Node n4 = new Node(Main.proj.eastNorth2latlon(en4));
             Way wnew = new Way(selectedSegment.way);
-            wnew.nodes.add(selectedSegment.lowerIndex+1, n3);
-            wnew.nodes.add(selectedSegment.lowerIndex+1, n4);
-            if (wnew.nodes.size() == 4) wnew.nodes.add(n1);
+            wnew.addNode(selectedSegment.lowerIndex+1, n3);
+            wnew.addNode(selectedSegment.lowerIndex+1, n4);
+            if (wnew.nodes.size() == 4) wnew.addNode(n1);
             Collection<Command> cmds = new LinkedList<Command>();
             cmds.add(new AddCommand(n4));
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 1312)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 1313)
@@ -177,5 +177,5 @@
             Way w = virtualWay.way;
             Way wnew = new Way(w);
-            wnew.nodes.add(virtualWay.lowerIndex+1, virtualNode);
+            wnew.addNode(virtualWay.lowerIndex+1, virtualNode);
             virtualCmds.add(new ChangeCommand(w, wnew));
             virtualCmds.add(new MoveCommand(virtualNode, dx, dy));
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 1312)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 1313)
@@ -56,4 +56,13 @@
         errors = null;
     }
+    /* This should not be called from outside. Fixing the UI to add relevant
+       get/set functions calling this implecitely is prefered, so we can have
+       transparent cache handling in the future. */
+    protected void clearCached()
+    {
+        mappaintVisibleCode = 0;
+        mappaintDrawnCode = 0;
+        mappaintStyle = null;
+    }
     /* end of mappaint data */
 
@@ -279,5 +288,6 @@
         tagged = osm.tagged;
         incomplete = osm.incomplete;
-        mappaintStyle = null;
+        clearCached();
+        clearErrors();
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 1312)
+++ trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 1313)
@@ -30,5 +30,11 @@
     public Integer mappaintDrawnAreaCode = 0;
     /* end of mappaint data */
-    
+    @Override protected void clearCached()
+    {
+        super.clearCached();
+        isMappaintArea = false;
+        mappaintDrawnAreaCode = 0;
+    }
+
     public void visitNodes(Visitor v) {
         for (Node n : this.nodes)
@@ -126,4 +132,16 @@
     }
 
+    public void addNode(Node n)
+    {
+        clearCached();
+        nodes.add(n);
+    }
+
+    public void addNode(int offs, Node n)
+    {
+        clearCached();
+        nodes.add(offs, n);
+    }
+
     public Boolean isClosed() {
         int s = nodes.size();
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java	(revision 1312)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java	(revision 1313)
@@ -93,12 +93,22 @@
     public ElemStyle getPrimitiveStyle(OsmPrimitive osm) {
         if(!useStyleCache)
-            return (styles != null) ? (IconElemStyle)styles.get(osm) : null;
+            return (styles != null) ? styles.get(osm) : null;
 
         if(osm.mappaintStyle == null && styles != null) {
-            osm.mappaintStyle =  styles.get(osm);
+            osm.mappaintStyle = styles.get(osm);
             if(osm instanceof Way)
                 ((Way)osm).isMappaintArea = styles.isArea(osm);
         }
         return osm.mappaintStyle;
+    }
+
+    public IconElemStyle getPrimitiveNodeStyle(OsmPrimitive osm) {
+        if(!useStyleCache)
+            return (styles != null) ? styles.getIcon(osm) : null;
+
+        if(osm.mappaintStyle == null && styles != null)
+            osm.mappaintStyle = styles.getIcon(osm);
+
+        return (IconElemStyle)osm.mappaintStyle;
     }
 
@@ -417,19 +427,4 @@
     }
 
-    public void drawSelectedRelation(Relation r)
-    {
-        for (RelationMember m : r.members)
-        {
-            if (m.member != null && !m.member.incomplete && !m.member.deleted
-            && !(m.member instanceof Relation))
-            {
-                /* nodes drawn on second call */
-                if(!(m.member instanceof Node))
-                    drawSelectedMember(m.member, styles != null ? styles.get(m.member)
-                    : null, true, true);
-            }
-        }
-    }
-
     public void drawSelectedMember(OsmPrimitive osm, ElemStyle style, Boolean area,
     Boolean areaselected)
@@ -463,5 +458,4 @@
 
         r.mappaintVisibleCode = 0;
-        /* TODO implement visible handling for relations too */
 
         // TODO: is it possible to do this like the nodes/ways code?
@@ -469,38 +463,39 @@
             return;
 
-        // draw multipolygon relations including their ways
-        // other relations are only drawn when selected
-
-        // we are in the "draw selected" phase
-        // TODO: is it necessary to check for r.selected?
-        if(r.selected && selectedCall)
+        if(selectedCall)
         {
             for (RelationMember m : r.members)
             {
                 if (m.member != null && !m.member.incomplete && !m.member.deleted
-                && (drawRestriction || m.member instanceof Node))
-                {
-                    drawSelectedMember(m.member, styles != null ? styles.get(m.member) : null, true, true);
+                && m.member instanceof Node)
+                {
+                    drawSelectedMember(m.member, styles != null ? getPrimitiveStyle(m.member) : null, true, true);
                 }
             }
             return;
         }
-
-        if (drawMultipolygon && r.keys != null && "multipolygon".equals(r.keys.get("type")))
-        {
-            drawMultipolygon(r);
-            return;
-        }
-
-        if (drawRestriction && r.keys != null && "restriction".equals(r.keys.get("type")))
+        else if (drawMultipolygon && r.keys != null && "multipolygon".equals(r.keys.get("type")))
+        {
+            if(drawMultipolygon(r))
+              return;
+        }
+        else if (drawRestriction && r.keys != null && "restriction".equals(r.keys.get("type")))
         {
             drawRestriction(r);
-            return;
-        }
-
-        if(r.selected)
-            drawSelectedRelation(r);
-    }
-
+        }
+
+        if(r.selected) /* draw ways*/
+        {
+            for (RelationMember m : r.members)
+            {
+                if (m.member != null && !m.member.incomplete && !m.member.deleted
+                && m.member instanceof Way) /* nodes drawn on second call */
+                {
+                    drawSelectedMember(m.member, styles != null ? getPrimitiveStyle(m.member)
+                    : null, true, true);
+                }
+            }
+        }
+    }
 
     // this current experimental implementation will only work for standard restrictions:
@@ -724,5 +719,5 @@
         }
 
-        IconElemStyle nodeStyle = (IconElemStyle)getPrimitiveStyle(r);
+        IconElemStyle nodeStyle = getPrimitiveNodeStyle(r);
 
         if (nodeStyle == null) {
@@ -748,5 +743,5 @@
     }
 
-    public void drawMultipolygon(Relation r) {
+    public Boolean drawMultipolygon(Relation r) {
         Collection<Way> inner = new LinkedList<Way>();
         Collection<Way> outer = new LinkedList<Way>();
@@ -754,4 +749,5 @@
         Collection<Way> outerclosed = new LinkedList<Way>();
         Boolean incomplete = false;
+        Boolean drawn = false;
 
         r.clearErrors();
@@ -787,5 +783,6 @@
                             outer.add(w);
                         else if(r.selected)
-                            drawSelectedMember(m.member, styles != null ? styles.get(m.member) : null, true, true);
+                            drawSelectedMember(m.member, styles != null
+                            ? getPrimitiveStyle(m.member) : null, true, true);
                     }
                 }
@@ -798,5 +795,5 @@
         }
 
-        ElemStyle wayStyle = styles != null ? styles.get(r) : null;
+        ElemStyle wayStyle = styles != null ? getPrimitiveStyle(r) : null;
         if(styles != null && (wayStyle == null || !(wayStyle instanceof AreaElemStyle)))
         {
@@ -806,4 +803,5 @@
                    wayStyle = styles.get(w);
             }
+            r.mappaintStyle = wayStyle;
         }
 
@@ -814,4 +812,5 @@
             Collection<Way> join = new LinkedList<Way>();
 
+            drawn = true;
             for (Way w : outer)
             {
@@ -954,9 +953,9 @@
                 for (Way wOuter : outer)
                     wOuter.mappaintVisibleCode = viewid;
-                return;
+                return drawn;
             }
             for (Way wInner : inner)
             {
-                ElemStyle innerStyle = styles.get(wInner);
+                ElemStyle innerStyle = getPrimitiveStyle(wInner);
                 if(innerStyle == null)
                 {
@@ -988,5 +987,5 @@
             for (Way wOuter : outer)
             {
-                ElemStyle outerStyle = styles.get(wOuter);
+                ElemStyle outerStyle = getPrimitiveStyle(wOuter);
                 if(outerStyle == null)
                 {
@@ -1016,6 +1015,5 @@
             }
         }
-        else if(r.selected)
-            drawSelectedRelation(r);
+        return drawn;
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 1312)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 1313)
@@ -29,5 +29,5 @@
             areas = new HashMap<String, AreaElemStyle>();
         }
-        private ElemStyle getNode(Map<String, String> keys)
+        private IconElemStyle getNode(Map<String, String> keys)
         {
             IconElemStyle ret = null;
@@ -120,5 +120,10 @@
         {
             return (osm.keys == null) ? null :
-            ((osm instanceof Node || osm instanceof Relation) ? getNode(osm.keys) : get(osm.keys));
+            ((osm instanceof Node) ? getNode(osm.keys) : get(osm.keys));
+        }
+
+        public IconElemStyle getIcon(OsmPrimitive osm)
+        {
+            return (osm.keys == null) ? null : getNode(osm.keys);
         }
 
