Index: trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 3151)
+++ trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 3152)
@@ -32,7 +32,7 @@
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
-import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -46,14 +46,16 @@
 public class SplitWayAction extends JosmAction {
 
-    private Way selectedWay;
-    private List<Node> selectedNodes;
 
     public static class SplitWayResult {
         private final Command command;
         private final List<? extends PrimitiveId> newSelection;
-
-        public SplitWayResult(Command command, List<? extends PrimitiveId> newSelection) {
+        private Way originalWay;
+        private List<Way> newWays;
+
+        public SplitWayResult(Command command, List<? extends PrimitiveId> newSelection, Way originalWay, List<Way> newWays) {
             this.command = command;
             this.newSelection = newSelection;
+            this.originalWay = originalWay;
+            this.newWays = newWays;
         }
 
@@ -64,4 +66,12 @@
         public List<? extends PrimitiveId> getNewSelection() {
             return newSelection;
+        }
+
+        public Way getOriginalWay() {
+            return originalWay;
+        }
+
+        public List<Way> getNewWays() {
+            return newWays;
         }
     }
@@ -85,4 +95,7 @@
 
         Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+
+        List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class);
+        List<Way> selectedWays = OsmPrimitive.getFilteredList(selection, Way.class);
 
         if (!checkSelection(selection)) {
@@ -96,29 +109,13 @@
         }
 
-        selectedWay = null;
-        selectedNodes = null;
-
-        Visitor splitVisitor = new AbstractVisitor() {
-            public void visit(Node n) {
-                if (selectedNodes == null) {
-                    selectedNodes = new LinkedList<Node>();
-                }
-                selectedNodes.add(n);
-            }
-            public void visit(Way w) {
-                selectedWay = w;
-            }
-            public void visit(Relation e) {
-                // enties are not considered
-            }
-        };
-
-        for (OsmPrimitive p : selection) {
-            p.visit(splitVisitor);
+
+        Way selectedWay = null;
+        if (!selectedWays.isEmpty()){
+            selectedWay = selectedWays.get(0);
         }
 
         // If only nodes are selected, try to guess which way to split. This works if there
         // is exactly one way that all nodes are part of.
-        if (selectedWay == null && selectedNodes != null) {
+        if (selectedWay == null && !selectedNodes.isEmpty()) {
             Map<Way, Integer> wayOccurenceCounter = new HashMap<Way, Integer>();
             for (Node n : selectedNodes) {
@@ -177,10 +174,8 @@
 
             // If a way and nodes are selected, verify that the nodes are part of the way.
-        } else if (selectedWay != null && selectedNodes != null) {
+        } else if (selectedWay != null && !selectedNodes.isEmpty()) {
 
             HashSet<Node> nds = new HashSet<Node>(selectedNodes);
-            for (Node n : selectedWay.getNodes()) {
-                nds.remove(n);
-            }
+            nds.removeAll(selectedWay.getNodes());
             if (!nds.isEmpty()) {
                 JOptionPane.showMessageDialog(Main.parent,
@@ -194,6 +189,8 @@
         }
 
-        // and then do the work.
-        splitWay();
+        List<List<Node>> wayChunks = buildSplitChunks(selectedWay, selectedNodes);
+        SplitWayResult result = splitWay(getEditLayer(),selectedWay, wayChunks);
+        Main.main.undoRedo.add(result.getCommand());
+        getCurrentDataSet().setSelected(result.getNewSelection());
     }
 
@@ -220,17 +217,26 @@
 
     /**
-     * Split a way into two or more parts, starting at a selected node.
+     * Splits the nodes of {@code wayToSplit} into a list of node sequences
+     * which are separated at the nodes in {@code splitPoints}.
+     * 
+     * This method displays warning messages if {@code wayToSplit} and/or
+     * {@code splitPoints} aren't consistent.
+     * 
+     * Returns null, if building the split chunks fails.
+     * 
+     * @param wayToSplit the way to split. Must not be null.
+     * @param splitPoints the nodes where the way is split. Must not be null.
+     * @return the list of chunks
      */
-    private void splitWay() {
-        // We take our way's list of nodes and copy them to a way chunk (a
-        // list of nodes).  Whenever we stumble upon a selected node, we start
-        // a new way chunk.
-
-        Set<Node> nodeSet = new HashSet<Node>(selectedNodes);
+    static public List<List<Node>> buildSplitChunks(Way wayToSplit, List<Node> splitPoints){
+        CheckParameterUtil.ensureParameterNotNull(wayToSplit, "wayToSplit");
+        CheckParameterUtil.ensureParameterNotNull(splitPoints, "splitPoints");
+
+        Set<Node> nodeSet = new HashSet<Node>(splitPoints);
         List<List<Node>> wayChunks = new LinkedList<List<Node>>();
         List<Node> currentWayChunk = new ArrayList<Node>();
         wayChunks.add(currentWayChunk);
 
-        Iterator<Node> it = selectedWay.getNodes().iterator();
+        Iterator<Node> it = wayToSplit.getNodes().iterator();
         while (it.hasNext()) {
             Node currentNode = it.next();
@@ -259,5 +265,5 @@
                         tr("Warning"),
                         JOptionPane.WARNING_MESSAGE);
-                return;
+                return null;
             }
             lastWayChunk.remove(lastWayChunk.size() - 1);
@@ -281,15 +287,17 @@
                         JOptionPane.WARNING_MESSAGE);
             }
-            return;
-        }
-        //Main.debug("wayChunks.size(): " + wayChunks.size());
-        //Main.debug("way id: " + selectedWay.id);
-
-        SplitWayResult result = splitWay(selectedWay, wayChunks);
-        Main.main.undoRedo.add(result.getCommand());
-        getCurrentDataSet().setSelected(result.getNewSelection());
-    }
-
-    public static SplitWayResult splitWay(Way way, List<List<Node>> wayChunks) {
+            return null;
+        }
+        return wayChunks;
+    }
+
+    /**
+     * Splits a way
+     * @param layer
+     * @param way
+     * @param wayChunks
+     * @return
+     */
+    public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks) {
         // build a list of commands, and also a new selection list
         Collection<Command> commandList = new ArrayList<Command>(wayChunks.size());
@@ -304,5 +312,5 @@
         newSelection.add(way);
 
-        Collection<Way> newWays = new ArrayList<Way>();
+        List<Way> newWays = new ArrayList<Way>();
         // Second, create new ways
         while (chunkIt.hasNext()) {
@@ -311,11 +319,11 @@
             newWays.add(wayToAdd);
             wayToAdd.setNodes(chunkIt.next());
-            commandList.add(new AddCommand(wayToAdd));
+            commandList.add(new AddCommand(layer,wayToAdd));
             //Main.debug("wayToAdd: " + wayToAdd);
             newSelection.add(wayToAdd);
 
         }
-        Boolean warnmerole = false;
-        Boolean warnme = false;
+        boolean warnmerole = false;
+        boolean warnme = false;
         // now copy all relations to new way also
 
@@ -442,5 +450,5 @@
 
             if (c != null) {
-                commandList.add(new ChangeCommand(r, c));
+                commandList.add(new ChangeCommand(layer,r, c));
             }
         }
@@ -459,8 +467,34 @@
         }
 
-        return new SplitWayResult(new SequenceCommand(tr("Split way {0} into {1} parts",
-                way.getDisplayName(DefaultNameFormatter.getInstance()),
-                wayChunks.size()),
-                commandList), newSelection);
+        return new SplitWayResult(
+                new SequenceCommand(
+                        tr("Split way {0} into {1} parts", way.getDisplayName(DefaultNameFormatter.getInstance()),wayChunks.size()),
+                        commandList
+                ),
+                newSelection,
+                way,
+                newWays
+        );
+    }
+
+    /**
+     * Splits the way {@code way} at the nodes in {@code atNodes} and replies
+     * the result of this process in an instance of {@see SplitWayResult}.
+     * 
+     * Note that changes are not applied to the data yet. You have to
+     * submit the command in {@see SplitWayResult#getCommand()} first,
+     * i.e. {@code Main.main.undoredo.add(result.getCommand())}.
+     * 
+     * Replies null if the way couldn't be split at the given nodes.
+     * 
+     * @param layer the layer which the way belongs to. Must not be null.
+     * @param way the way to split. Must not be null.
+     * @param atNodes the list of nodes where the way is split. Must not be null.
+     * @return the result from the split operation
+     */
+    static public SplitWayResult split(OsmDataLayer layer, Way way, List<Node> atNodes){
+        List<List<Node>> chunks = buildSplitChunks(way, atNodes);
+        if (chunks == null) return null;
+        return splitWay(layer,way, chunks);
     }
 
Index: trunk/src/org/openstreetmap/josm/command/ChangeCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/ChangeCommand.java	(revision 3151)
+++ trunk/src/org/openstreetmap/josm/command/ChangeCommand.java	(revision 3152)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -27,6 +28,13 @@
     private final OsmPrimitive newOsm;
 
+
     public ChangeCommand(OsmPrimitive osm, OsmPrimitive newOsm) {
         super();
+        this.osm = osm;
+        this.newOsm = newOsm;
+    }
+
+    public ChangeCommand(OsmDataLayer layer, OsmPrimitive osm, OsmPrimitive newOsm) {
+        super(layer);
         this.osm = osm;
         this.newOsm = newOsm;
@@ -47,7 +55,7 @@
         String msg = "";
         switch(OsmPrimitiveType.from(osm)) {
-            case NODE: msg = marktr("Change node {0}"); break;
-            case WAY: msg = marktr("Change way {0}"); break;
-            case RELATION: msg = marktr("Change relation {0}"); break;
+        case NODE: msg = marktr("Change node {0}"); break;
+        case WAY: msg = marktr("Change way {0}"); break;
+        case RELATION: msg = marktr("Change relation {0}"); break;
         }
         return new DefaultMutableTreeNode(
Index: trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 3151)
+++ trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 3152)
@@ -407,5 +407,5 @@
             chunks.add(n1);
             chunks.add(n2);
-            return SplitWayAction.splitWay(ws.way, chunks).getCommand();
+            return SplitWayAction.splitWay(layer,ws.way, chunks).getCommand();
         }
     }
