Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 987)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 988)
@@ -7,27 +7,13 @@
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.*;
-import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.DeleteCommand;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.WaySegment;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.RelationMember;
-import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
-import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.tools.*;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -88,7 +74,7 @@
 		Command c;
 		if (ctrl) {
-			c = deleteWithReferences(Main.ds.getSelected());
+			c = DeleteCommand.deleteWithReferences(Main.ds.getSelected());
 		} else {
-			c = delete(Main.ds.getSelected(), !alt);
+			c = DeleteCommand.delete(Main.ds.getSelected(), !alt);
 		}
 		if (c != null) {
@@ -97,5 +83,5 @@
 
 		Main.map.repaint();
-    }
+	}
 
 	/**
@@ -118,15 +104,15 @@
 			if (ws != null) {
 				if (shift) {
-					c = deleteWaySegment(ws); 
+					c = DeleteCommand.deleteWaySegment(ws); 
 				} else if (ctrl) {
-					c = deleteWithReferences(Collections.singleton((OsmPrimitive)ws.way));
+					c = DeleteCommand.deleteWithReferences(Collections.singleton((OsmPrimitive)ws.way));
 				} else {
-					c = delete(Collections.singleton((OsmPrimitive)ws.way), !alt);
+					c = DeleteCommand.delete(Collections.singleton((OsmPrimitive)ws.way), !alt);
 				}
 			}
 		} else if (ctrl) {
-			c = deleteWithReferences(Collections.singleton(sel));
+			c = DeleteCommand.deleteWithReferences(Collections.singleton(sel));
 		} else {
-			c = delete(Collections.singleton(sel), !alt);
+			c = DeleteCommand.delete(Collections.singleton(sel), !alt);
 		}
 		if (c != null) {
@@ -136,232 +122,4 @@
 		Main.map.mapView.repaint();
 	}
-
-	/**
-	 * Delete the primitives and everything they reference.
-	 * 
-	 * If a node is deleted, the node and all ways and relations
-	 * the node is part of are deleted as well.
-	 * 
-	 * If a way is deleted, all relations the way is member of are also deleted.
-	 * 
-	 * If a way is deleted, only the way and no nodes are deleted.
-	 * 
-	 * @param selection The list of all object to be deleted.
-	 * @return command A command to perform the deletions, or null of there is
-	 * nothing to delete.
-	 */
-	private Command deleteWithReferences(Collection<OsmPrimitive> selection) {
-		CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds);
-		for (OsmPrimitive osm : selection)
-			osm.visit(v);
-		v.data.addAll(selection);
-		if (v.data.isEmpty()) 
-			return null;
-		return new DeleteCommand(v.data);
-	}
-
-	/**
-	 * Try to delete all given primitives.
-	 *
-	 * If a node is used by a way, it's removed from that way.  If a node or a
-	 * way is used by a relation, inform the user and do not delete.
-	 *
-	 * If this would cause ways with less than 2 nodes to be created, delete
-	 * these ways instead.  If they are part of a relation, inform the user
-	 * and do not delete.
-	 * 
-	 * @param selection The objects to delete.
-	 * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well
-	 * @return command A command to perform the deletions, or null of there is
-	 * nothing to delete.
-	 */
-	private int testRelation(Relation ref, OsmPrimitive osm)
-	{
-		NameVisitor n = new NameVisitor();
-		ref.visit(n);
-		NameVisitor s = new NameVisitor();
-		osm.visit(s);
-		String role = new String();
-		for (RelationMember m : ref.members)
-		{
-			if (m.member == osm)
-			{
-				role = m.role;
-				break;
-			}
-		}
-		if (role.length() > 0)
-		{
-			return JOptionPane.showConfirmDialog(Main.parent,
-			tr("Selection \"{0}\" is used by relation \"{1}\" with role {2}.\nDelete from relation?", s.name, n.name, role),
-			tr("Conflicting relation"), JOptionPane.YES_NO_OPTION);
-		}
-		else
-		{
-			return JOptionPane.showConfirmDialog(Main.parent,
-			tr("Selection \"{0}\" is used by relation \"{1}\".\nDelete from relation?", s.name, n.name),
-			tr("Conflicting relation"), JOptionPane.YES_NO_OPTION);
-		}
-	}
-
-	private Command delete(Collection<OsmPrimitive> selection, boolean alsoDeleteNodesInWay) {
-		if (selection.isEmpty()) return null;
-
-		Collection<OsmPrimitive> del = new HashSet<OsmPrimitive>(selection);
-		Collection<Way> waysToBeChanged = new HashSet<Way>();
-		HashMap<OsmPrimitive, Collection<OsmPrimitive>> relationsToBeChanged = new HashMap<OsmPrimitive, Collection<OsmPrimitive>>();
-
-		if (alsoDeleteNodesInWay) {
-			// Delete untagged nodes that are to be unreferenced.
-			Collection<OsmPrimitive> delNodes = new HashSet<OsmPrimitive>();
-			for (OsmPrimitive osm : del) {
-				if (osm instanceof Way) {
-					for (Node n : ((Way)osm).nodes) {
-						if (!n.tagged) {
-							CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
-							n.visit(v);
-							v.data.removeAll(del);
-							if (v.data.isEmpty()) {
-								delNodes.add(n);
-							}
-						}
-					}
-				}
-			}
-			del.addAll(delNodes);
-		}
-		
-		for (OsmPrimitive osm : del) {
-			CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
-			osm.visit(v);
-			for (OsmPrimitive ref : v.data) {
-				if (del.contains(ref)) continue;
-				if (ref instanceof Way) {
-					waysToBeChanged.add((Way) ref);
-				} else if (ref instanceof Relation) {
-					if (testRelation((Relation)ref, osm) == JOptionPane.YES_OPTION)
-					{
-						Collection<OsmPrimitive> relset = relationsToBeChanged.get(ref);
-						if(relset == null) relset = new HashSet<OsmPrimitive>();
-						relset.add(osm);
-						relationsToBeChanged.put(ref, relset);
-					}
-					else
-						return null;
-				} else {
-					return null;
-				}
-			}
-		}
-
-		Collection<Command> cmds = new LinkedList<Command>();
-		for (Way w : waysToBeChanged) {
-			Way wnew = new Way(w);
-			wnew.nodes.removeAll(del);
-			if (wnew.nodes.size() < 2) {
-				del.add(w);
-
-				CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
-				w.visit(v);
-				for (OsmPrimitive ref : v.data) {
-					if (del.contains(ref)) continue;
-					if (ref instanceof Relation) {
-						Boolean found = false;
-						Collection<OsmPrimitive> relset = relationsToBeChanged.get(ref);
-						if (relset == null)
-							relset = new HashSet<OsmPrimitive>();
-						else
-						{
-							for (OsmPrimitive m : relset) {
-								if(m == w)
-								{
-									found = true;
-									break;
-								}
-							}
-						}
-						if (!found)
-						{
-							if (testRelation((Relation)ref, w) == JOptionPane.YES_OPTION)
-							{
-								relset.add(w);
-								relationsToBeChanged.put(ref, relset);
-							}
-							else
-								return null;
-						}
-					} else {
-						return null;
-					}
-				}
-			} else {
-				cmds.add(new ChangeCommand(w, wnew));
-			}
-		}
-
-		Iterator<OsmPrimitive> iterator = relationsToBeChanged.keySet().iterator();
-		while(iterator.hasNext())
-		{
-			Relation cur = (Relation)iterator.next();
-			Relation rel = new Relation(cur);
-			for(OsmPrimitive osm : relationsToBeChanged.get(cur))
-			{
-				for (RelationMember rm : rel.members) {
-					if (rm.member == osm)
-					{
-						RelationMember mem = new RelationMember();
-						mem.role = rm.role;
-						mem.member = rm.member;
-						rel.members.remove(mem);
-						break;
-					}
-				}
-			}
-			cmds.add(new ChangeCommand(cur, rel));
-		}
-
-		if (!del.isEmpty()) cmds.add(new DeleteCommand(del));
-
-		return new SequenceCommand(tr("Delete"), cmds);
-	}
-
-	private Command deleteWaySegment(WaySegment ws) {
-		List<Node> n1 = new ArrayList<Node>(),
-			n2 = new ArrayList<Node>();
-
-		n1.addAll(ws.way.nodes.subList(0, ws.lowerIndex + 1));
-		n2.addAll(ws.way.nodes.subList(ws.lowerIndex + 1, ws.way.nodes.size()));
-
-		if (n1.size() < 2 && n2.size() < 2) {
-			return new DeleteCommand(Collections.singleton(ws.way));
-		}
-		
-		Way wnew = new Way(ws.way);
-		wnew.nodes.clear();
-
-		if (n1.size() < 2) {
-			wnew.nodes.addAll(n2);
-			return new ChangeCommand(ws.way, wnew);
-		} else if (n2.size() < 2) {
-			wnew.nodes.addAll(n1);
-			return new ChangeCommand(ws.way, wnew);
-		} else {
-			Collection<Command> cmds = new LinkedList<Command>();
-
-			wnew.nodes.addAll(n1);
-			cmds.add(new ChangeCommand(ws.way, wnew));
-
-			Way wnew2 = new Way();
-			if (wnew.keys != null) {
-				wnew2.keys = new HashMap<String, String>(wnew.keys);
-				wnew2.checkTagged();
-                                wnew2.checkDirectionTagged();
-			}
-			wnew2.nodes.addAll(n2);
-			cmds.add(new AddCommand(wnew2));
-
-			return new SequenceCommand(tr("Split way segment"), cmds);
-		}
-	}
 	
 	@Override public String getModeHelpText() {
Index: trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 987)
+++ trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 988)
@@ -5,12 +5,26 @@
 import static org.openstreetmap.josm.tools.I18n.trn;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 
 import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.MutableTreeNode;
 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.WaySegment;
+import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -84,3 +98,236 @@
 		return root;
 	}
+
+	/**
+	 * Delete the primitives and everything they reference.
+	 *
+	 * If a node is deleted, the node and all ways and relations
+	 * the node is part of are deleted as well.
+	 *
+	 * If a way is deleted, all relations the way is member of are also deleted.
+	 * 
+	 * If a way is deleted, only the way and no nodes are deleted.
+	 * 
+	 * @param selection The list of all object to be deleted.
+	 * @return command A command to perform the deletions, or null of there is
+	 * nothing to delete.
+	 */
+	public static Command deleteWithReferences(Collection<? extends OsmPrimitive> selection) {
+		CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds);
+		for (OsmPrimitive osm : selection)
+			osm.visit(v);
+		v.data.addAll(selection);
+		if (v.data.isEmpty()) 
+			return null;
+		return new DeleteCommand(v.data);
+	}
+
+	/**
+	 * Try to delete all given primitives.
+	 *
+	 * If a node is used by a way, it's removed from that way.  If a node or a
+	 * way is used by a relation, inform the user and do not delete.
+	 *
+	 * If this would cause ways with less than 2 nodes to be created, delete
+	 * these ways instead.  If they are part of a relation, inform the user
+	 * and do not delete.
+	 * 
+	 * @param selection The objects to delete.
+	 * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well
+	 * @return command A command to perform the deletions, or null of there is
+	 * nothing to delete.
+	 */
+	private static int testRelation(Relation ref, OsmPrimitive osm)
+	{
+		NameVisitor n = new NameVisitor();
+		ref.visit(n);
+		NameVisitor s = new NameVisitor();
+		osm.visit(s);
+		String role = new String();
+		for (RelationMember m : ref.members)
+		{
+			if (m.member == osm)
+			{
+				role = m.role;
+				break;
+			}
+		}
+		if (role.length() > 0)
+		{
+			return JOptionPane.showConfirmDialog(Main.parent,
+			tr("Selection \"{0}\" is used by relation \"{1}\" with role {2}.\nDelete from relation?", s.name, n.name, role),
+			tr("Conflicting relation"), JOptionPane.YES_NO_OPTION);
+		}
+		else
+		{
+			return JOptionPane.showConfirmDialog(Main.parent,
+			tr("Selection \"{0}\" is used by relation \"{1}\".\nDelete from relation?", s.name, n.name),
+			tr("Conflicting relation"), JOptionPane.YES_NO_OPTION);
+		}
+	}
+
+	public static Command delete(Collection<? extends OsmPrimitive> selection)
+	{
+		return delete(selection, true);
+	}
+
+	public static Command delete(Collection<? extends OsmPrimitive> selection, boolean alsoDeleteNodesInWay) {
+		if (selection.isEmpty()) return null;
+
+		Collection<OsmPrimitive> del = new HashSet<OsmPrimitive>(selection);
+		Collection<Way> waysToBeChanged = new HashSet<Way>();
+		HashMap<OsmPrimitive, Collection<OsmPrimitive>> relationsToBeChanged = new HashMap<OsmPrimitive, Collection<OsmPrimitive>>();
+
+		if (alsoDeleteNodesInWay) {
+			// Delete untagged nodes that are to be unreferenced.
+			Collection<OsmPrimitive> delNodes = new HashSet<OsmPrimitive>();
+			for (OsmPrimitive osm : del) {
+				if (osm instanceof Way) {
+					for (Node n : ((Way)osm).nodes) {
+						if (!n.tagged) {
+							CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
+							n.visit(v);
+							v.data.removeAll(del);
+							if (v.data.isEmpty()) {
+								delNodes.add(n);
+							}
+						}
+					}
+				}
+			}
+			del.addAll(delNodes);
+		}
+		
+		for (OsmPrimitive osm : del) {
+			CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
+			osm.visit(v);
+			for (OsmPrimitive ref : v.data) {
+				if (del.contains(ref)) continue;
+				if (ref instanceof Way) {
+					waysToBeChanged.add((Way) ref);
+				} else if (ref instanceof Relation) {
+					if (testRelation((Relation)ref, osm) == JOptionPane.YES_OPTION)
+					{
+						Collection<OsmPrimitive> relset = relationsToBeChanged.get(ref);
+						if(relset == null) relset = new HashSet<OsmPrimitive>();
+						relset.add(osm);
+						relationsToBeChanged.put(ref, relset);
+					}
+					else
+						return null;
+				} else {
+					return null;
+				}
+			}
+		}
+
+		Collection<Command> cmds = new LinkedList<Command>();
+		for (Way w : waysToBeChanged) {
+			Way wnew = new Way(w);
+			wnew.nodes.removeAll(del);
+			if (wnew.nodes.size() < 2) {
+				del.add(w);
+
+				CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
+				w.visit(v);
+				for (OsmPrimitive ref : v.data) {
+					if (del.contains(ref)) continue;
+					if (ref instanceof Relation) {
+						Boolean found = false;
+						Collection<OsmPrimitive> relset = relationsToBeChanged.get(ref);
+						if (relset == null)
+							relset = new HashSet<OsmPrimitive>();
+						else
+						{
+							for (OsmPrimitive m : relset) {
+								if(m == w)
+								{
+									found = true;
+									break;
+								}
+							}
+						}
+						if (!found)
+						{
+							if (testRelation((Relation)ref, w) == JOptionPane.YES_OPTION)
+							{
+								relset.add(w);
+								relationsToBeChanged.put(ref, relset);
+							}
+							else
+								return null;
+						}
+					} else {
+						return null;
+					}
+				}
+			} else {
+				cmds.add(new ChangeCommand(w, wnew));
+			}
+		}
+
+		Iterator<OsmPrimitive> iterator = relationsToBeChanged.keySet().iterator();
+		while(iterator.hasNext())
+		{
+			Relation cur = (Relation)iterator.next();
+			Relation rel = new Relation(cur);
+			for(OsmPrimitive osm : relationsToBeChanged.get(cur))
+			{
+				for (RelationMember rm : rel.members) {
+					if (rm.member == osm)
+					{
+						RelationMember mem = new RelationMember();
+						mem.role = rm.role;
+						mem.member = rm.member;
+						rel.members.remove(mem);
+						break;
+					}
+				}
+			}
+			cmds.add(new ChangeCommand(cur, rel));
+		}
+
+		if (!del.isEmpty()) cmds.add(new DeleteCommand(del));
+
+		return new SequenceCommand(tr("Delete"), cmds);
+	}
+
+	public static Command deleteWaySegment(WaySegment ws) {
+		List<Node> n1 = new ArrayList<Node>(),
+			n2 = new ArrayList<Node>();
+
+		n1.addAll(ws.way.nodes.subList(0, ws.lowerIndex + 1));
+		n2.addAll(ws.way.nodes.subList(ws.lowerIndex + 1, ws.way.nodes.size()));
+
+		if (n1.size() < 2 && n2.size() < 2) {
+			return new DeleteCommand(Collections.singleton(ws.way));
+		}
+		
+		Way wnew = new Way(ws.way);
+		wnew.nodes.clear();
+
+		if (n1.size() < 2) {
+			wnew.nodes.addAll(n2);
+			return new ChangeCommand(ws.way, wnew);
+		} else if (n2.size() < 2) {
+			wnew.nodes.addAll(n1);
+			return new ChangeCommand(ws.way, wnew);
+		} else {
+			Collection<Command> cmds = new LinkedList<Command>();
+
+			wnew.nodes.addAll(n1);
+			cmds.add(new ChangeCommand(ws.way, wnew));
+
+			Way wnew2 = new Way();
+			if (wnew.keys != null) {
+				wnew2.keys = new HashMap<String, String>(wnew.keys);
+				wnew2.checkTagged();
+                                wnew2.checkDirectionTagged();
+			}
+			wnew2.nodes.addAll(n2);
+			cmds.add(new AddCommand(wnew2));
+
+			return new SequenceCommand(tr("Split way segment"), cmds);
+		}
+	}
 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java	(revision 987)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java	(revision 988)
@@ -320,7 +320,19 @@
 		tr("Highlight the member from the current table row as JOSM's selection"), KeyEvent.VK_S, new ActionListener() {
 			public void actionPerformed(ActionEvent e) {
-				int[] rows = memberTable.getSelectedRows();
-				ArrayList<OsmPrimitive> sel = new ArrayList<OsmPrimitive>(rows.length);
-				for (int i : rows) { sel.add((OsmPrimitive)memberTable.getValueAt(i, 1)); }
+				ArrayList<OsmPrimitive> sel;
+				int cnt = memberTable.getSelectedRowCount();
+				if(cnt > 0)
+				{
+					sel = new ArrayList<OsmPrimitive>(cnt);
+					for (int i : memberTable.getSelectedRows())
+						sel.add((OsmPrimitive)memberTable.getValueAt(i, 1));
+				}
+				else
+				{
+					cnt = memberTable.getRowCount();
+					sel = new ArrayList<OsmPrimitive>(cnt);
+					for (int i = 0; i < cnt; ++i)
+						sel.add((OsmPrimitive)memberTable.getValueAt(i, 1));
+				}
 				Main.ds.setSelected(sel);
 			}
