Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 4628)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 4629)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
 
@@ -176,4 +177,6 @@
         private Rectangle2D bounds;
         private final Collection<Way> ways;
+        private final List<Node> nodes;
+        private final List<PolyData> inners;
 
         public PolyData(JoinedWay joinedWay, Collection<Way> refWays) {
@@ -183,8 +186,14 @@
         public PolyData(List<Node> nodes, boolean selected, Collection<Way> refWays) {
             this.ways = Collections.unmodifiableCollection(refWays);
+            this.nodes = Collections.unmodifiableList(nodes);
             this.selected = selected;
-            boolean initial = true;
+            this.inners = new ArrayList<Multipolygon.PolyData>();
             this.poly = new Path2D.Double();
             this.poly.setWindingRule(Path2D.WIND_EVEN_ODD);
+            buildPoly();
+        }
+        
+        private void buildPoly() {
+            boolean initial = true;
             for (Node n : nodes)
             {
@@ -198,4 +207,7 @@
             }
             poly.closePath();
+            for (PolyData inner : inners) {
+                appendInner(inner.poly);
+            }
         }
 
@@ -203,5 +215,7 @@
             this.selected = copy.selected;
             this.poly = (Double) copy.poly.clone();
-            this.ways = new ArrayList<Way>(copy.ways);
+            this.ways = Collections.unmodifiableCollection(copy.ways);
+            this.nodes = Collections.unmodifiableList(copy.nodes);
+            this.inners = new ArrayList<Multipolygon.PolyData>(copy.inners);
         }
         
@@ -225,5 +239,10 @@
         }
 
-        public void addInner(Path2D.Double inner) {
+        public void addInner(PolyData inner) {
+            inners.add(inner);
+            appendInner(inner.poly);
+        }
+        
+        private void appendInner(Path2D.Double inner) {
             poly.append(inner.getPathIterator(null), false);
         }
@@ -242,4 +261,24 @@
         public Collection<Way> getWays() {
             return ways;
+        }
+        
+        private void resetPoly() {
+            poly.reset();
+            buildPoly();
+            bounds = null;
+        }
+        
+        public void nodeMoved(NodeMovedEvent event) {
+            final Node n = event.getNode();
+            boolean innerChanged = false;
+            for (PolyData inner : inners) {
+                if (inner.nodes.contains(n)) {
+                    inner.resetPoly();
+                    innerChanged = true;
+                }
+            }
+            if (nodes.contains(n) || innerChanged) {
+                resetPoly();
+            }
         }
     }
@@ -441,5 +480,5 @@
             PolyData combinedOuter = new PolyData(outerPolygons.get(0));
             for (PolyData inner: innerPolygons) {
-                combinedOuter.addInner(inner.poly);
+                combinedOuter.addInner(inner);
             }
             combinedPolygons.add(combinedOuter);
@@ -454,5 +493,5 @@
                     o = outerPolygons.get(0);
                 }
-                o.addInner(pdInner.poly);
+                o.addInner(pdInner);
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java	(revision 4628)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java	(revision 4629)
@@ -120,20 +120,16 @@
     }
     
-    private static final void removeMultipolygonFrom(Relation mp, Collection<Map<Relation, Multipolygon>> maps) {
-        for (Map<Relation, Multipolygon> map : maps) {
-            map.remove(mp);
-        }
-    }
-
-    private final void removeMultipolygonsReferringTo(AbstractDatasetChangedEvent event) {
-        removeMultipolygonsReferringTo(event.getPrimitives(), event.getDataset());
-    }
-
-    private final void removeMultipolygonsReferringTo(Collection<? extends OsmPrimitive> primitives, DataSet ds) {
-        removeMultipolygonsReferringTo(primitives, ds, null);
-    }
-    
-    private final Collection<Map<Relation, Multipolygon>> removeMultipolygonsReferringTo(
-            Collection<? extends OsmPrimitive> primitives, DataSet ds, Collection<Map<Relation, Multipolygon>> initialMaps) {
+    private final void updateMultipolygonsReferringTo(final AbstractDatasetChangedEvent event) {
+        updateMultipolygonsReferringTo(event, event.getPrimitives(), event.getDataset());
+    }
+
+    private final void updateMultipolygonsReferringTo(
+            final AbstractDatasetChangedEvent event, final Collection<? extends OsmPrimitive> primitives, final DataSet ds) {
+        updateMultipolygonsReferringTo(event, primitives, ds, null);
+    }
+    
+    private final Collection<Map<Relation, Multipolygon>> updateMultipolygonsReferringTo(
+            final AbstractDatasetChangedEvent event, final Collection<? extends OsmPrimitive> primitives, 
+            final DataSet ds, final Collection<Map<Relation, Multipolygon>> initialMaps) {
         Collection<Map<Relation, Multipolygon>> maps = initialMaps;
         if (primitives != null) {
@@ -143,5 +139,5 @@
                         maps = getMapsFor(ds);
                     }
-                    removeMultipolygonFrom((Relation) p, maps);
+                    processEvent(event, (Relation) p, maps);
                     
                 } else if (p instanceof Way && p.getDataSet() != null) {
@@ -151,13 +147,29 @@
                                 maps = getMapsFor(ds);
                             }
-                            removeMultipolygonFrom((Relation) ref, maps);
+                            processEvent(event, (Relation) ref, maps);
                         }
                     }
                 } else if (p instanceof Node && p.getDataSet() != null) {
-                    maps = removeMultipolygonsReferringTo(p.getReferrers(), ds, maps);
+                    maps = updateMultipolygonsReferringTo(event, p.getReferrers(), ds, maps);
                 }
             }
         }
         return maps;
+    }
+    
+    private final void processEvent(final AbstractDatasetChangedEvent event, final Relation r, final Collection<Map<Relation, Multipolygon>> maps) {
+        if (event instanceof NodeMovedEvent) {
+            for (Map<Relation, Multipolygon> map : maps) {
+                Multipolygon m = map.get(r);
+                for (PolyData pd : m.getCombinedPolygons()) {
+                    pd.nodeMoved((NodeMovedEvent) event);
+                }
+            }
+        } else {
+            // Default (non-optimal) action: remove multipolygon from cache 
+            for (Map<Relation, Multipolygon> map : maps) {
+                map.remove(r);
+            }
+        }
     }
 
@@ -169,5 +181,5 @@
     @Override
     public void primitivesRemoved(PrimitivesRemovedEvent event) {
-        removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
+        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     }
 
@@ -179,25 +191,25 @@
     @Override
     public void nodeMoved(NodeMovedEvent event) {
-        removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
+        updateMultipolygonsReferringTo(event);
     }
 
     @Override
     public void wayNodesChanged(WayNodesChangedEvent event) {
-        removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
+        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     }
 
     @Override
     public void relationMembersChanged(RelationMembersChangedEvent event) {
-        removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
+        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     }
 
     @Override
     public void otherDatasetChange(AbstractDatasetChangedEvent event) {
-        removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
+        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     }
 
     @Override
     public void dataChanged(DataChangedEvent event) {
-        removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
+        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     }
 
