Index: /trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 2409)
+++ /trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 2410)
@@ -2,6 +2,6 @@
 package org.openstreetmap.josm.actions;
 
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 
 import java.awt.event.ActionEvent;
@@ -157,6 +157,5 @@
         cmds.add(new ChangeCommand(selectedNode, c));
 
-        Node n = new Node(selectedNode);
-        n.clearOsmId();
+        Node n = new Node(selectedNode, true);
 
         // If this wasn't called from menu, place it where the cursor is/was
@@ -302,6 +301,5 @@
             if (originalNode == pushNode) {
                 // clone the node for all other ways
-                pushNode = new Node(pushNode);
-                pushNode.clearOsmId();
+                pushNode = new Node(pushNode, true);
                 newNodes.add(pushNode);
                 cmds.add(new AddCommand(pushNode));
Index: /trunk/src/org/openstreetmap/josm/command/UndeletePrimitivesCommand.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/command/UndeletePrimitivesCommand.java	(revision 2409)
+++ /trunk/src/org/openstreetmap/josm/command/UndeletePrimitivesCommand.java	(revision 2410)
@@ -6,4 +6,5 @@
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.logging.Logger;
 
@@ -25,9 +26,6 @@
 
     /** the node to undelete */
-    private ArrayList<OsmPrimitive> toUndelete;
+    private final List<OsmPrimitive> toUndelete = new ArrayList<OsmPrimitive>();
 
-    protected UndeletePrimitivesCommand() {
-        toUndelete = new ArrayList<OsmPrimitive>();
-    }
     /**
      * constructor
@@ -35,5 +33,4 @@
      */
     public UndeletePrimitivesCommand(OsmPrimitive node) {
-        this();
         toUndelete.add(node);
     }
@@ -44,5 +41,4 @@
      */
     public UndeletePrimitivesCommand(OsmPrimitive ... toUndelete) {
-        this();
         for (int i=0; i < toUndelete.length; i++) {
             this.toUndelete.add(toUndelete[i]);
Index: /trunk/src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 2409)
+++ /trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 2410)
@@ -68,9 +68,21 @@
 
     /**
+     * 
+     * @param clone
+     * @param clearId If true, set version to 0 and id to new unique value
+     */
+    public Node(Node clone, boolean clearId) {
+        super(clone.getUniqueId(), true);
+        cloneFrom(clone);
+        if (clearId) {
+            clearOsmId();
+        }
+    }
+
+    /**
      * Create an identical clone of the argument (including the id)
      */
     public Node(Node clone) {
-        super(clone.getUniqueId(), true);
-        cloneFrom(clone);
+        this(clone, false);
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2409)
+++ /trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2410)
@@ -378,4 +378,5 @@
      * @throws IllegalArgumentException thrown if id <= 0
      * @throws IllegalArgumentException thrown if version <= 0
+     * @throws DataIntegrityProblemException If id is changed and primitive was already added to the dataset
      */
     public void setOsmId(long id, int version) {
@@ -384,4 +385,6 @@
         if (version <= 0)
             throw new IllegalArgumentException(tr("Version > 0 expected. Got {0}.", version));
+        if (dataSet != null && id != this.id)
+            throw new DataIntegrityProblemException("Id cannot be changed after primitive was added to the dataset");
         this.id = id;
         this.version = version;
@@ -391,21 +394,14 @@
     /**
      * Clears the id and version known to the OSM API. The id and the version is set to 0.
-     * incomplete is set to false.
+     * incomplete is set to false. It's preferred to use copy constructor with clearId set to true instead
+     * of calling this method.
      *
      * <strong>Caution</strong>: Do not use this method on primitives which are already added to a {@see DataSet}.
-     * Ways and relations might already refer to the primitive and clearing the OSM ID
-     * result in corrupt data.
-     *
-     * Here's an example use case:
-     * <pre>
-     *     // create a clone of an already existing node
-     *     Node copy = new Node(otherExistingNode);
-     *
-     *     // reset the clones OSM id
-     *     copy.clearOsmId();
-     * </pre>
-     *
+     *
+     * @throws DataIntegrityProblemException If primitive was already added to the dataset
      */
     public void clearOsmId() {
+        if (dataSet != null)
+            throw new DataIntegrityProblemException("Method cannot be called after primitive was added to the dataset");
         this.id = generateUniqueId();
         this.version = 0;
Index: /trunk/src/org/openstreetmap/josm/data/osm/Relation.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 2409)
+++ /trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 2410)
@@ -140,10 +140,17 @@
     }
 
-    /**
-     * Create an identical clone of the argument (including the id)
-     */
-    public Relation(Relation clone) {
+    public Relation(Relation clone, boolean clearId) {
         super(clone.getUniqueId(), true);
         cloneFrom(clone);
+        if (clearId) {
+            clearOsmId();
+        }
+    }
+
+    /**
+     * Create an identical clone of the argument (including the id)
+     */
+    public Relation(Relation clone) {
+        this(clone, false);
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 2409)
+++ /trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 2410)
@@ -149,11 +149,23 @@
 
     /**
-     * Create an identical clone of the argument (including the id).
-     *
-     * @param original  the original way. Must not be null.
-     */
-    public Way(Way original) {
+     * 
+     * @param original
+     * @param clearId
+     */
+    public Way(Way original, boolean clearId) {
         super(original.getUniqueId(), true);
         cloneFrom(original);
+        if (clearId) {
+            clearOsmId();
+        }
+    }
+
+    /**
+     * Create an identical clone of the argument (including the id).
+     *
+     * @param original  the original way. Must not be null.
+     */
+    public Way(Way original) {
+        this(original, false);
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 2409)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 2410)
@@ -471,7 +471,5 @@
 
         public void launchEditorForDuplicate(Relation original) {
-            Relation copy = new Relation(original.getId());
-            copy.cloneFrom(original);
-            copy.clearOsmId();
+            Relation copy = new Relation(original, true);
             copy.setModified(true);
             RelationEditor editor = RelationEditor.getEditor(
Index: /trunk/src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 2409)
+++ /trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 2410)
@@ -92,8 +92,6 @@
 
         public void copyTo(OsmPrimitive osm) {
-            //  id < 0 possible if read from a file
-            if (id <= 0) {
-                osm.clearOsmId();
-            } else {
+            // It's not necessary to call clearOsmId for id < 0. The same thing is done by parameterless constructor
+            if (id > 0) {
                 osm.setOsmId(id, version);
             }
