Index: trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 2496)
+++ trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 2497)
@@ -90,5 +90,5 @@
                 int count = 0;
                 for (Way w : OsmPrimitive.getFilteredList(n.getReferrers(), Way.class)) {
-                    if (w.isDeleted() || w.incomplete || w.getNodesCount() < 1) {
+                    if (w.isDeleted() || w.incomplete) {
                         continue;
                     }
@@ -353,5 +353,5 @@
             // modify all ways containing the nodes
             for (Way w : OsmPrimitive.getFilteredList(selectedNode.getReferrers(), Way.class)) {
-                if (w.isDeleted() || w.incomplete || w.getNodesCount() < 1) {
+                if (w.isDeleted() || w.incomplete) {
                     continue;
                 }
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2496)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2497)
@@ -47,4 +47,6 @@
     private Map<PrimitiveId, OsmPrimitive> primitivesMap = allPrimitives.foreignKey(new IdHash());
     private List<DataSetListener> listeners = new ArrayList<DataSetListener>();
+    // Number of open calls to beginUpdate
+    private int updateCount;
 
     /**
@@ -796,39 +798,90 @@
     }
 
+    /**
+     * Can be called before bigger changes on dataset. Events are disabled until {@link #endUpdate()}.
+     * {@link DataSetListener#dataChanged()} event is triggered after end of changes
+     * <br>
+     * Typical usecase should look like this:
+     * <pre>
+     * ds.beginUpdate();
+     * try {
+     *   ...
+     * } finally {
+     *   ds.endUpdate();
+     * }
+     * </pre>
+     */
+    public void beginUpdate() {
+        updateCount++;
+    }
+
+    /**
+     * @see DataSet#beginUpdate()
+     */
+    public void endUpdate() {
+        if (updateCount > 0) {
+            updateCount--;
+            if (updateCount == 0) {
+                fireDataChanged();
+            }
+        } else
+            throw new AssertionError("endUpdate called without beginUpdate");
+    }
+
+    private void fireDataChanged() {
+        if (updateCount == 0) {
+            for (DataSetListener dsl : listeners) {
+                dsl.dataChanged();
+            }
+        }
+    }
+
     void firePrimitivesAdded(Collection<? extends OsmPrimitive> added) {
-        for (DataSetListener dsl : listeners) {
-            dsl.primtivesAdded(added);
+        if (updateCount == 0) {
+            for (DataSetListener dsl : listeners) {
+                dsl.primtivesAdded(added);
+            }
         }
     }
 
     void firePrimitivesRemoved(Collection<? extends OsmPrimitive> removed) {
-        for (DataSetListener dsl : listeners) {
-            dsl.primtivesRemoved(removed);
+        if (updateCount == 0) {
+            for (DataSetListener dsl : listeners) {
+                dsl.primtivesRemoved(removed);
+            }
         }
     }
 
     void fireTagsChanged(OsmPrimitive prim) {
-        for (DataSetListener dsl : listeners) {
-            dsl.tagsChanged(prim);
+        if (updateCount == 0) {
+            for (DataSetListener dsl : listeners) {
+                dsl.tagsChanged(prim);
+            }
         }
     }
 
     void fireRelationMembersChanged(Relation r) {
-        for (DataSetListener dsl : listeners) {
-            dsl.relationMembersChanged(r);
-        }
-    }
-
-    public void fireNodeMoved(Node node) {
+        if (updateCount == 0) {
+            for (DataSetListener dsl : listeners) {
+                dsl.relationMembersChanged(r);
+            }
+        }
+    }
+
+    void fireNodeMoved(Node node) {
         reindexNode(node);
-        for (DataSetListener dsl : listeners) {
-            dsl.nodeMoved(node);
-        }
-    }
-
-    public void fireWayNodesChanged(Way way) {
+        if (updateCount == 0) {
+            for (DataSetListener dsl : listeners) {
+                dsl.nodeMoved(node);
+            }
+        }
+    }
+
+    void fireWayNodesChanged(Way way) {
         reindexWay(way);
-        for (DataSetListener dsl : listeners) {
-            dsl.wayNodesChanged(way);
+        if (updateCount == 0) {
+            for (DataSetListener dsl : listeners) {
+                dsl.wayNodesChanged(way);
+            }
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSetListener.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSetListener.java	(revision 2496)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSetListener.java	(revision 2497)
@@ -37,5 +37,5 @@
      * @param added A collection of newly-visible primitives
      */
-    public void primtivesAdded(Collection<? extends OsmPrimitive> added);
+    void primtivesAdded(Collection<? extends OsmPrimitive> added);
 
     /**
@@ -45,5 +45,5 @@
      * @param removed A collection of newly-invisible primitives
      */
-    public void primtivesRemoved(Collection<? extends OsmPrimitive> removed);
+    void primtivesRemoved(Collection<? extends OsmPrimitive> removed);
 
     /**
@@ -53,5 +53,5 @@
      * @param prim the primitive, whose tags were affected.
      */
-    public void tagsChanged(OsmPrimitive prim);
+    void tagsChanged(OsmPrimitive prim);
 
     /**
@@ -59,5 +59,5 @@
      * @param node The node that was moved.
      */
-    public void nodeMoved(Node node);
+    void nodeMoved(Node node);
 
     /**
@@ -65,5 +65,5 @@
      * @param way The way that was modified.
      */
-    public void wayNodesChanged(Way way);
+    void wayNodesChanged(Way way);
 
     /**
@@ -71,6 +71,11 @@
      * @param relation The relation that was modified.
      */
-    public void relationMembersChanged(Relation r);
+    void relationMembersChanged(Relation r);
 
+    /**
+     * Called after big changes in dataset. Usually other events are stopped using Dataset.beginUpdate() and
+     * after operation is completed (Dataset.endUpdate()), {@link #dataChanged()} is called.
+     */
+    void dataChanged();
 
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java	(revision 2496)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java	(revision 2497)
@@ -333,14 +333,19 @@
         if (sourceDataSet == null)
             return;
-        for (Node node: sourceDataSet.getNodes()) {
-            mergePrimitive(node);
-        }
-        for (Way way: sourceDataSet.getWays()) {
-            mergePrimitive(way);
-        }
-        for (Relation relation: sourceDataSet.getRelations()) {
-            mergePrimitive(relation);
-        }
-        fixReferences();
+        targetDataSet.beginUpdate();
+        try {
+            for (Node node: sourceDataSet.getNodes()) {
+                mergePrimitive(node);
+            }
+            for (Way way: sourceDataSet.getWays()) {
+                mergePrimitive(way);
+            }
+            for (Relation relation: sourceDataSet.getRelations()) {
+                mergePrimitive(relation);
+            }
+            fixReferences();
+        } finally {
+            targetDataSet.endUpdate();
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 2496)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 2497)
@@ -788,4 +788,11 @@
     }
 
+    public void dataChanged() {
+        Layer l = Main.main.getEditLayer();
+        if (l != null) {
+            initFromLayer(l);
+        }
+    }
+
     /* ---------------------------------------------------------------------------------- */
     /* DataSetListener                                                                    */
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 2496)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 2497)
@@ -822,4 +822,8 @@
     }
 
+    public void dataChanged() {
+        dataChanged(getEditLayer());
+    }
+
     /* ---------------------------------------------------------------------- */
     /* DataChangeListener                                                    */
Index: trunk/src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 2496)
+++ trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 2497)
@@ -563,7 +563,12 @@
 
             progressMonitor.subTask(tr("Preparing data set..."));
-            reader.processNodesAfterParsing();
-            reader.processWaysAfterParsing();
-            reader.processRelationsAfterParsing();
+            reader.ds.beginUpdate();
+            try {
+                reader.processNodesAfterParsing();
+                reader.processWaysAfterParsing();
+                reader.processRelationsAfterParsing();
+            } finally {
+                reader.ds.endUpdate();
+            }
             progressMonitor.worked(1);
             return reader.getDataSet();
