Index: src/org/openstreetmap/josm/command/Command.java
===================================================================
--- src/org/openstreetmap/josm/command/Command.java	(revision 17085)
+++ src/org/openstreetmap/josm/command/Command.java	(working copy)
@@ -227,7 +227,7 @@
         for (OsmPrimitive osm : primitives) {
             if (osm.isIncomplete()) {
                 res |= IS_INCOMPLETE;
-            } else if ((osm.isOutsideDownloadArea()
+            } else if ((res & IS_OUTSIDE) == 0 && (osm.isOutsideDownloadArea()
                     || (osm instanceof Node && !osm.isNew() && osm.getDataSet() != null && osm.getDataSet().getDataSourceBounds().isEmpty()))
                             && (ignore == null || !ignore.contains(osm))) {
                 res |= IS_OUTSIDE;
Index: src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 17085)
+++ src/org/openstreetmap/josm/command/DeleteCommand.java	(working copy)
@@ -184,23 +184,25 @@
     @Override
     public boolean executeCommand() {
         ensurePrimitivesAreInDataset();
-        // Make copy and remove all references (to prevent inconsistent dataset (delete referenced) while command is executed)
-        for (OsmPrimitive osm: toDelete) {
-            if (osm.isDeleted())
-                throw new IllegalArgumentException(osm + " is already deleted");
-            clonedPrimitives.put(osm, osm.save());
 
-            if (osm instanceof Way) {
-                ((Way) osm).setNodes(null);
-            } else if (osm instanceof Relation) {
-                ((Relation) osm).setMembers(null);
+        getAffectedDataSet().update(() -> {
+            // Make copy and remove all references (to prevent inconsistent dataset (delete referenced) while command is executed)
+            for (OsmPrimitive osm : toDelete) {
+                if (osm.isDeleted())
+                    throw new IllegalArgumentException(osm + " is already deleted");
+                clonedPrimitives.put(osm, osm.save());
+
+                if (osm instanceof Way) {
+                    ((Way) osm).setNodes(null);
+                } else if (osm instanceof Relation) {
+                    ((Relation) osm).setMembers(null);
+                }
             }
-        }
 
-        for (OsmPrimitive osm: toDelete) {
-            osm.setDeleted(true);
-        }
-
+            for (OsmPrimitive osm : toDelete) {
+                osm.setDeleted(true);
+            }
+        });
         return true;
     }
 
@@ -208,13 +210,15 @@
     public void undoCommand() {
         ensurePrimitivesAreInDataset();
 
-        for (OsmPrimitive osm: toDelete) {
-            osm.setDeleted(false);
-        }
+        getAffectedDataSet().update(() -> {
+            for (OsmPrimitive osm : toDelete) {
+                osm.setDeleted(false);
+            }
 
-        for (Entry<OsmPrimitive, PrimitiveData> entry: clonedPrimitives.entrySet()) {
-            entry.getKey().load(entry.getValue());
-        }
+            for (Entry<OsmPrimitive, PrimitiveData> entry : clonedPrimitives.entrySet()) {
+                entry.getKey().load(entry.getValue());
+            }
+        });
     }
 
     @Override
@@ -426,12 +430,13 @@
         Collection<Command> cmds = new LinkedList<>();
         Set<Node> nodesToRemove = new HashSet<>(Utils.filteredCollection(primitivesToDelete, Node.class));
         for (Way w : waysToBeChanged) {
-            Way wnew = new Way(w);
-            wnew.removeNodes(nodesToRemove);
-            if (wnew.getNodesCount() < 2) {
+            if (primitivesToDelete.contains(w))
+                continue;
+            List<Node> remainingNodes = w.calculateRemoveNodes(nodesToRemove);
+            if (remainingNodes.size() < 2) {
                 primitivesToDelete.add(w);
             } else {
-                cmds.add(new ChangeNodesCommand(w, wnew.getNodes()));
+                cmds.add(new ChangeNodesCommand(w, remainingNodes));
             }
         }
 
Index: src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/Way.java	(revision 17085)
+++ src/org/openstreetmap/josm/data/osm/Way.java	(working copy)
@@ -363,18 +363,7 @@
         if (selection == null || isIncomplete()) return;
         boolean locked = writeLock();
         try {
-            boolean closed = isClosed() && selection.contains(lastNode());
-            List<Node> copy = Arrays.stream(nodes)
-                    .filter(n -> !selection.contains(n))
-                    .collect(Collectors.toList());
-
-            int i = copy.size();
-            if (closed && i > 2) {
-                copy.add(copy.get(0));
-            } else if (i >= 2 && i <= 3 && copy.get(0) == copy.get(i-1)) {
-                copy.remove(i-1);
-            }
-            setNodes(removeDouble(copy));
+            setNodes(calculateRemoveNodes(selection));
             for (Node n : selection) {
                 n.clearCachedStyle();
             }
@@ -384,6 +373,29 @@
     }
 
     /**
+     * Calculate the remaining nodes after a removal of the given set of {@link Node nodes} from this way.
+     * @param selection The selection of nodes to remove. Ignored, if null
+     * @return result of the removal, can be empty
+     * @since xxx
+     */
+    public List<Node> calculateRemoveNodes(Set<? extends Node> selection) {
+        if (selection == null || isIncomplete())
+            return getNodes();
+        boolean closed = isClosed() && selection.contains(lastNode());
+        List<Node> copy = Arrays.stream(nodes)
+                .filter(n -> !selection.contains(n))
+                .collect(Collectors.toList());
+
+        int i = copy.size();
+        if (closed && i > 2) {
+            copy.add(copy.get(0));
+        } else if (i >= 2 && i <= 3 && copy.get(0) == copy.get(i-1)) {
+            copy.remove(i-1);
+        }
+        return removeDouble(copy);
+    }
+
+    /**
      * Adds a node to the end of the list of nodes. Ignored, if n is null.
      *
      * @param n the node. Ignored, if null
