Index: src/org/openstreetmap/josm/actions/PurgeAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/PurgeAction.java	(revision 5904)
+++ src/org/openstreetmap/josm/actions/PurgeAction.java	(working copy)
@@ -97,19 +97,23 @@
 
         // Add referrer, unless the object to purge is not new
         // and the parent is a relation
+        HashSet<OsmPrimitive> toPurgeRecursive = new HashSet<OsmPrimitive>();
         while (!toPurge.isEmpty()) {
-            OsmPrimitive osm = toPurge.iterator().next();
+
+          for (OsmPrimitive osm: toPurge) {
             for (OsmPrimitive parent: osm.getReferrers()) {
-                if (toPurge.contains(parent) || toPurgeChecked.contains(parent)) {
+                if (toPurge.contains(parent) || toPurgeChecked.contains(parent) || toPurgeRecursive.contains(parent)) {
                     continue;
                 }
                 if (parent instanceof Way || (parent instanceof Relation && osm.isNew())) {
                     toPurgeAdditionally.add(parent);
-                    toPurge.add(parent);
+                    toPurgeRecursive.add(parent);
                 }
             }
-            toPurge.remove(osm);
             toPurgeChecked.add(osm);
+          }
+          toPurge = toPurgeRecursive;
+          toPurgeRecursive = new HashSet<OsmPrimitive>();
         }
 
         makeIncomplete = new HashSet<OsmPrimitive>();
Index: src/org/openstreetmap/josm/command/PurgeCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/PurgeCommand.java	(revision 5904)
+++ src/org/openstreetmap/josm/command/PurgeCommand.java	(working copy)
@@ -132,6 +132,9 @@
 
         List<OsmPrimitive> out = new ArrayList<OsmPrimitive>(in.size());
 
+        // Nodes not deleted in the first pass
+        Set<OsmPrimitive> remainingNodes = new HashSet<OsmPrimitive>(in.size());
+
         /**
          *  First add nodes that have no way referrer.
          */
@@ -142,6 +145,8 @@
                     Node n = (Node) u;
                     for (OsmPrimitive ref : n.getReferrers()) {
                         if (ref instanceof Way && in.contains(ref)) {
+                            it.remove();
+                            remainingNodes.add(n);
                             continue outer;
                         }
                     }
@@ -153,25 +158,24 @@
         /**
          * Then add all ways, each preceded by its (remaining) nodes.
          */
-        top: while (!in.isEmpty()) {
-            for (Iterator<OsmPrimitive> it = in.iterator(); it.hasNext();) {
-                OsmPrimitive u = it.next();
-                if (u instanceof Way) {
-                    Way w = (Way) u;
-                    it.remove();
-                    for (Node n : w.getNodes()) {
-                        if (in.contains(n)) {
-                            in.remove(n);
-                            out.add(n);
-                        }
+        for (Iterator<OsmPrimitive> it = in.iterator(); it.hasNext();) {
+            OsmPrimitive u = it.next();
+            if (u instanceof Way) {
+                Way w = (Way) u;
+                it.remove();
+                for (Node n : w.getNodes()) {
+                    if (remainingNodes.contains(n)) {
+                        remainingNodes.remove(n);
+                        out.add(n);
                     }
-                    out.add(w);
-                    continue top;
                 }
+                out.add(w);
             }
-            break; // no more ways left
         }
 
+        if (!remainingNodes.isEmpty())
+            throw new AssertionError("topo sort algorithm failed (nodes remaining)");
+
         /**
             * Rest are relations. Do topological sorting on a DAG where each
             * arrow points from child to parent. (Because it is faster to
