Index: trunk/src/org/openstreetmap/josm/command/AddCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/AddCommand.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/AddCommand.java	(revision 630)
@@ -44,6 +44,7 @@
 	}
 
-	@Override public void executeCommand() {
+	@Override public boolean executeCommand() {
 		osm.visit(new AddVisitor(ds));
+		return true;
 	}
 
Index: trunk/src/org/openstreetmap/josm/command/ChangeCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/ChangeCommand.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/ChangeCommand.java	(revision 630)
@@ -29,8 +29,9 @@
     }
 
-	@Override public void executeCommand() {
+	@Override public boolean executeCommand() {
 	    super.executeCommand();
 	    osm.cloneFrom(newOsm);
 	    osm.modified = true;
+		return true;
     }
 
Index: trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java	(revision 630)
@@ -52,5 +52,5 @@
 	}
 	
-	@Override public void executeCommand() {
+	@Override public boolean executeCommand() {
 		super.executeCommand(); // save old
 		if (value == null) {
@@ -65,4 +65,5 @@
 			}
 		}
+		return true;
 	}
 
Index: trunk/src/org/openstreetmap/josm/command/Command.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/Command.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/Command.java	(revision 630)
@@ -10,4 +10,6 @@
 import javax.swing.tree.MutableTreeNode;
 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
@@ -31,78 +33,102 @@
 abstract public class Command {
 
-	private static final class CloneVisitor implements Visitor {
-		public Map<OsmPrimitive, OsmPrimitive> orig = new HashMap<OsmPrimitive, OsmPrimitive>();
+   private static final class CloneVisitor implements Visitor {
+      public Map<OsmPrimitive, OsmPrimitive> orig = new HashMap<OsmPrimitive, OsmPrimitive>();
 
-		public void visit(Node n) {
-			orig.put(n, new Node(n));
-		}
-		public void visit(Way w) {
-			orig.put(w, new Way(w));
-		}
-		public void visit(Relation e) {
-			orig.put(e, new Relation(e));
-		}
-	}
+      public void visit(Node n) {
+         orig.put(n, new Node(n));
+      }
+      public void visit(Way w) {
+         orig.put(w, new Way(w));
+      }
+      public void visit(Relation e) {
+         orig.put(e, new Relation(e));
+      }
+   }
 
-	private CloneVisitor orig; 
+   private CloneVisitor orig; 
 
-	/**
-	 * Executes the command on the dataset. This implementation will remember all
-	 * primitives returned by fillModifiedData for restoring them on undo.
-	 */
-	public void executeCommand() {
-		orig = new CloneVisitor();
-		Collection<OsmPrimitive> all = new HashSet<OsmPrimitive>();
-		fillModifiedData(all, all, all);
-		for (OsmPrimitive osm : all)
-			osm.visit(orig);
-	}
+   protected DataSet ds;
 
-	/**
-	 * Undoes the command. 
-	 * It can be assumed, that all objects are in the same state they were before.
-	 * It can also be assumed that executeCommand was called exactly once before.
-	 * 
-	 * This implementation undoes all objects stored by a former call to executeCommand.
-	 */
-	public void undoCommand() {
-		for (Entry<OsmPrimitive, OsmPrimitive> e : orig.orig.entrySet())
-			e.getKey().cloneFrom(e.getValue());
-	}
+   public Command() {
+      this.ds = Main.main.editLayer().data;
+   }
+   /**
+    * Executes the command on the dataset. This implementation will remember all
+    * primitives returned by fillModifiedData for restoring them on undo.
+    */
+   public boolean did_execute = false;
+   public boolean executeCommand() {
+      did_execute = true;
+      orig = new CloneVisitor();
+      Collection<OsmPrimitive> all = new HashSet<OsmPrimitive>();
+      fillModifiedData(all, all, all);
+      for (OsmPrimitive osm : all)
+         osm.visit(orig);
+      return true;
+   }
 
+   /**
+    * Undoes the command. 
+    * It can be assumed, that all objects are in the same state they were before.
+    * It can also be assumed that executeCommand was called exactly once before.
+    * 
+    * This implementation undoes all objects stored by a former call to executeCommand.
+    */
+   public void undoCommand() {
+      for (Entry<OsmPrimitive, OsmPrimitive> e : orig.orig.entrySet())
+         e.getKey().cloneFrom(e.getValue());
+   }
 
-	/**
-	 * Called, when a layer has been removed to have the command remove itself from
-	 * any buffer if it is not longer applicable to the dataset (e.g. it was part of
-	 * the removed layer)
-	 */
-	public boolean invalidBecauselayerRemoved(Layer oldLayer) {
-		if (!(oldLayer instanceof OsmDataLayer))
-			return false;
-		HashSet<OsmPrimitive> modified = new HashSet<OsmPrimitive>();
-		fillModifiedData(modified, modified, modified);
-		if (modified.isEmpty())
-			return false;
+   /**
+    * Called, when a layer has been removed to have the command remove itself from
+    * any buffer if it is not longer applicable to the dataset (e.g. it was part of
+    * the removed layer)
+    */
+   public boolean invalidBecauselayerRemoved(Layer oldLayer) {
+      if (!(oldLayer instanceof OsmDataLayer))
+         return false;
+      HashSet<OsmPrimitive> modified = new HashSet<OsmPrimitive>();
+      fillModifiedData(modified, modified, modified);
+      if (modified.isEmpty())
+         return false;
 
-		HashSet<OsmPrimitive> all = new HashSet<OsmPrimitive>(((OsmDataLayer)oldLayer).data.allPrimitives());
-		for (OsmPrimitive osm : all)
-			if (all.contains(osm))
-				return true;
+      HashSet<OsmPrimitive> all = new HashSet<OsmPrimitive>(((OsmDataLayer)oldLayer).data.allPrimitives());
+      for (OsmPrimitive osm : all)
+         if (all.contains(osm))
+                 return true;
 
-		return false;
-	}
+      return false;
+   }
 
-	/**
-	 * Fill in the changed data this command operates on.
-	 * Add to the lists, don't clear them.
-	 * 
-	 * @param modified  The modified primitives
-	 * @param deleted   The deleted primitives
-	 * @param added		The added primitives
-	 */
-	abstract public void fillModifiedData(Collection<OsmPrimitive> modified,
-			Collection<OsmPrimitive> deleted,
-			Collection<OsmPrimitive> added);
+    /**
+     * Lets other commands access the original version
+     * of the object. Usually for undoing.
+     */
+    public OsmPrimitive getOrig(OsmPrimitive osm) {
+        OsmPrimitive o = orig.orig.get(osm);
+        if (o != null)
+             return o;
+        Main.debug("unable to find osm with id: " + osm.id + " hashCode: " + osm.hashCode());
+        for (OsmPrimitive t : orig.orig.keySet()) {
+             OsmPrimitive to = orig.orig.get(t);
+             Main.debug("now: " + t.id + " hashCode: " + t.hashCode());
+             Main.debug("orig: " + to.id + " hashCode: " + to.hashCode());
+        }
+        return o;
+    }
 
-	abstract public MutableTreeNode description();
+   /**
+    * Fill in the changed data this command operates on.
+    * Add to the lists, don't clear them.
+    * 
+    * @param modified  The modified primitives
+    * @param deleted   The deleted primitives
+    * @param added      The added primitives
+    */
+   abstract public void fillModifiedData(Collection<OsmPrimitive> modified,
+         Collection<OsmPrimitive> deleted,
+         Collection<OsmPrimitive> added);
+
+   abstract public MutableTreeNode description();
 }
Index: trunk/src/org/openstreetmap/josm/command/ConflictResolveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/ConflictResolveCommand.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/ConflictResolveCommand.java	(revision 630)
@@ -36,5 +36,5 @@
 	}
 
-	@Override public void executeCommand() {
+	@Override public boolean executeCommand() {
 		super.executeCommand();
 
@@ -57,4 +57,5 @@
 			conflictDialog.rebuildList();
  		}
+		return true;
 	}
 
Index: trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 630)
@@ -6,4 +6,5 @@
 
 import java.util.Collection;
+import java.util.Collections;
 
 import javax.swing.JLabel;
@@ -26,13 +27,24 @@
 	private final Collection<? extends OsmPrimitive> data;
 
+    /** 
+     * Constructor for a collection of data
+     */
 	public DeleteCommand(Collection<? extends OsmPrimitive> data) {
 		this.data = data;
 	}
+    /** 
+     * Constructor for a single data item. Use the collection 
+     * constructor to delete multiple objects.
+     */
+    public DeleteCommand(OsmPrimitive data) {
+        this.data = Collections.singleton(data);
+    }
 
-	@Override public void executeCommand() {
+	@Override public boolean executeCommand() {
 		super.executeCommand();
 		for (OsmPrimitive osm : data) {
 			osm.delete(true);
 		}
+		return true;
 	}
 	
Index: trunk/src/org/openstreetmap/josm/command/MoveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/MoveCommand.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/MoveCommand.java	(revision 630)
@@ -95,5 +95,5 @@
 	}
 	
-	@Override public void executeCommand() {
+	@Override public boolean executeCommand() {
 		for (Node n : objects) {
 			n.eastNorth = new EastNorth(n.eastNorth.east()+x, n.eastNorth.north()+y);
@@ -101,4 +101,5 @@
 			n.modified = true;
 		}
+		return true;
 	}
 
Index: trunk/src/org/openstreetmap/josm/command/RemoveRelationMemberCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/RemoveRelationMemberCommand.java	(revision 630)
+++ trunk/src/org/openstreetmap/josm/command/RemoveRelationMemberCommand.java	(revision 630)
@@ -0,0 +1,68 @@
+// License: GPL. Copyright 2007 by Immanuel Scholz and others
+package org.openstreetmap.josm.command;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Collection;
+
+import javax.swing.JLabel;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.MutableTreeNode;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.*;
+
+import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
+
+/**
+ * Command that adds a relation to an OSM object
+ *
+ * @author daveh
+ */
+public class RemoveRelationMemberCommand extends Command {
+
+    // container object in which to replace a sub object
+    private final Relation relation;
+    // the sub-object to be replaced
+    private final RelationMember member;
+    // its replacement
+    private int location = -1;
+
+    public RemoveRelationMemberCommand(Relation _relation, RelationMember _member) {
+        this.relation = _relation;
+        this.member = _member;
+    }
+    public RemoveRelationMemberCommand(Relation _relation, RelationMember _member, int _location) {
+        this.relation = _relation;
+        this.member = _member;
+        location = _location;
+    }
+
+    @Override public boolean executeCommand() {
+        super.executeCommand();
+        int removed_at = relation.members.indexOf(member);
+        relation.members.remove(member);
+        if ((location != -1) && (removed_at != location)) {
+            relation.members.add(removed_at, member);
+            Main.debug("error removing relation member");
+            return false;
+        }
+        relation.modified = true;
+        return true;
+    }
+
+    @Override public void undoCommand() {
+        super.undoCommand();
+        relation.members.add(member);
+        relation.modified = this.getOrig(relation).modified;
+    }
+
+    @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {}
+
+    @Override public MutableTreeNode description() {
+        NameVisitor v = new NameVisitor();
+        relation.visit(v);
+        return new DefaultMutableTreeNode(new JLabel(tr("RemoveRelationMember")+" "+tr(v.className)+" "+v.name, v.icon, JLabel.HORIZONTAL));
+    }
+}
Index: trunk/src/org/openstreetmap/josm/command/RotateCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/RotateCommand.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/RotateCommand.java	(revision 630)
@@ -113,6 +113,7 @@
 	}
 	
-	@Override public void executeCommand() {
+	@Override public boolean executeCommand() {
 		rotateNodes(true);
+		return true;
 	}
 
Index: trunk/src/org/openstreetmap/josm/command/SequenceCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/SequenceCommand.java	(revision 629)
+++ trunk/src/org/openstreetmap/josm/command/SequenceCommand.java	(revision 630)
@@ -10,4 +10,5 @@
 import javax.swing.tree.MutableTreeNode;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 
@@ -23,5 +24,7 @@
 	 */
 	private Command[] sequence;
+	private boolean sequence_complete;
 	private final String name;
+	public boolean continueOnError = false;
 
 	/**
@@ -42,12 +45,32 @@
 	}
 	
-	@Override public void executeCommand() {
-		for (Command c : sequence)
-			c.executeCommand();
+	public int executed_commands = 0;
+	@Override public boolean executeCommand() {
+		for (int i=0; i < sequence.length; i++) {
+			Command c = sequence[i];
+			boolean result = c.executeCommand();
+			if (!result)
+				Main.debug("SequenceCommand, executing command[" + i + "] " +  c + " result: " + result);
+			if (!result && !continueOnError) {
+				this.undoCommands(i-1);
+				return false;
+			}
+		}
+		sequence_complete = true;
+		return true;
+	}
+
+	private void undoCommands(int start) {
+		// We probably aborted this halfway though the
+		// execution sequence because of a sub-command
+		// error.  We already undid the sub-commands.
+		if (!sequence_complete)
+			return;
+		for (int i = start; i >= 0; --i)
+			sequence[i].undoCommand();
 	}
 
 	@Override public void undoCommand() {
-		for (int i = sequence.length-1; i >= 0; --i)
-			sequence[i].undoCommand();
+		this.undoCommands(sequence.length-1);
 	}
 
