Index: src/org/openstreetmap/josm/command/AddPrimitivesCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/AddPrimitivesCommand.java	(revision 3695)
+++ src/org/openstreetmap/josm/command/AddPrimitivesCommand.java	(working copy)
@@ -10,6 +10,7 @@
 
 import javax.swing.JLabel;
 
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.NodeData;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -18,8 +19,11 @@
 
 public class AddPrimitivesCommand extends Command {
 
-    private final List<PrimitiveData> data = new ArrayList<PrimitiveData>();
+    private List<PrimitiveData> data = new ArrayList<PrimitiveData>();
 
+    // only filled on undo
+    private List<OsmPrimitive> createdPrimitives = null;
+
     public AddPrimitivesCommand(List<PrimitiveData> data) {
         this.data.addAll(data);
     }
@@ -31,43 +35,70 @@
 
     @SuppressWarnings("null")
     @Override public boolean executeCommand() {
+        List<OsmPrimitive> newPrimitives;
+        if (createdPrimitives == null) { // first time execution
+            newPrimitives = new ArrayList<OsmPrimitive>(data.size());
 
-        List<OsmPrimitive> createdPrimitives = new ArrayList<OsmPrimitive>(data.size());
+            for (PrimitiveData pd:data) {
+                OsmPrimitive primitive = getLayer().data.getPrimitiveById(pd);
+                boolean created = primitive == null;
+                if (created) {
+                    primitive = pd.getType().newInstance(pd.getUniqueId(), true);
+                }
+                if (pd instanceof NodeData) { // Load nodes immediately because they can't be added to dataset without coordinates
+                    primitive.load(pd);
+                }
+                if (created) {
+                    getLayer().data.addPrimitive(primitive);
+                }
+                newPrimitives.add(primitive);
+            }
 
-        for (PrimitiveData pd:data) {
-            OsmPrimitive primitive = getLayer().data.getPrimitiveById(pd);
-            boolean created = primitive == null;
-            if (created) {
-                primitive = pd.getType().newInstance(pd.getUniqueId(), true);
+            //Then load ways and relations
+            for (int i=0; i<newPrimitives.size(); i++) {
+                if (!(newPrimitives.get(i) instanceof Node)) {
+                    newPrimitives.get(i).load(data.get(i));
+                }
             }
-            if (pd instanceof NodeData) { // Load nodes immediately because they can't be added to dataset without coordinates
-                primitive.load(pd);
+        } else { // redo
+            // When redoing this command, we have to add the same objects, otherwise
+            // a subsequent command (e.g. MoveCommand) cannot be redone.
+            for (OsmPrimitive osm : createdPrimitives) {
+                getLayer().data.addPrimitive(osm);
             }
-            if (created) {
-                getLayer().data.addPrimitive(primitive);
-            }
-            createdPrimitives.add(primitive);
+            newPrimitives = createdPrimitives;
         }
 
-        //Then load ways and relations
-        for (int i=0; i<createdPrimitives.size(); i++) {
-            if (!(createdPrimitives.get(i) instanceof Node)) {
-                createdPrimitives.get(i).load(data.get(i));
-            }
-        }
-
-        getLayer().data.setSelected(createdPrimitives);
+        getLayer().data.setSelected(newPrimitives);
         return true;
     }
 
     @Override public void undoCommand() {
-        for (PrimitiveData p:data) {
-            getLayer().data.removePrimitive(p);
+        DataSet ds = getLayer().data;
+        
+        if (createdPrimitives == null) {
+            createdPrimitives = new ArrayList<OsmPrimitive>(data.size());
+            
+            for (PrimitiveData p : data) {
+                createdPrimitives.add(ds.getPrimitiveById(p));
+            }
+            createdPrimitives = PurgeCommand.topoSort(createdPrimitives);
+            
+            for (PrimitiveData p : data) {
+                ds.removePrimitive(p);
+            }
+            data = null;
+            
+        } else {
+            for (OsmPrimitive osm : createdPrimitives) {
+                ds.removePrimitive(osm);
+            }
         }
     }
 
     @Override public JLabel getDescription() {
-        return new JLabel(trn("Added {0} object", "Added {0} objects", data.size(), data.size()), null,
+        int size = data != null ? data.size() : createdPrimitives.size();
+        return new JLabel(trn("Added {0} object", "Added {0} objects", size, size), null,
                 JLabel.HORIZONTAL
         );
     }
@@ -80,6 +111,9 @@
 
     @Override
     public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
+        if (createdPrimitives != null)
+            return createdPrimitives;
+        
         Collection<OsmPrimitive> prims = new HashSet<OsmPrimitive>();
         for (PrimitiveData d : data) {
             OsmPrimitive osm = getLayer().data.getPrimitiveById(d);
