Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 10506)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 10507)
@@ -658,5 +658,4 @@
             public void initialize() {
                 validator = new OsmValidator();
-                getLayerManager().addLayerChangeListener(validator);
             }
         });
Index: trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 10506)
+++ trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 10507)
@@ -60,9 +60,4 @@
 import org.openstreetmap.josm.data.validation.tests.WayConnectedToArea;
 import org.openstreetmap.josm.data.validation.tests.WronglyOrderedWays;
-import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
-import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
-import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
-import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.layer.ValidatorLayer;
 import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
@@ -75,5 +70,5 @@
  * @author Francisco R. Santos &lt;frsantos@gmail.com&gt;
  */
-public class OsmValidator implements LayerChangeListener {
+public class OsmValidator {
 
     public static volatile ValidatorLayer errorLayer;
@@ -346,28 +341,3 @@
     }
 
-    /* -------------------------------------------------------------------------- */
-    /* interface LayerChangeListener                                              */
-    /* -------------------------------------------------------------------------- */
-    @Override
-    public void layerAdded(LayerAddEvent e) {
-        // do nothing
-    }
-
-    @Override
-    public void layerOrderChanged(LayerOrderChangeEvent e) {
-        // do nothing
-    }
-
-    @Override
-    public void layerRemoving(LayerRemoveEvent e) {
-        if (e.getRemovedLayer() == errorLayer) {
-            errorLayer = null;
-            return;
-        }
-        if (e.getSource().getLayersOfType(OsmDataLayer.class).isEmpty()) {
-            if (errorLayer != null) {
-                Main.getLayerManager().removeLayer(errorLayer);
-            }
-        }
-    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/LayerManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/LayerManager.java	(revision 10506)
+++ trunk/src/org/openstreetmap/josm/gui/layer/LayerManager.java	(revision 10507)
@@ -3,6 +3,10 @@
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -98,4 +102,5 @@
         private final Layer removedLayer;
         private final boolean lastLayer;
+        private Collection<Layer> scheduleForRemoval = new ArrayList<>();
 
         LayerRemoveEvent(LayerManager source, Layer removedLayer) {
@@ -120,4 +125,18 @@
         public boolean isLastLayer() {
             return lastLayer;
+        }
+
+        /**
+         * Schedule the removal of other layers after this layer has been deleted.
+         * <p>
+         * Dupplicate removal requests are ignored.
+         * @param layers The layers to remove.
+         * @since 10507
+         */
+        public void scheduleRemoval(Collection<? extends Layer> layers) {
+            for (Layer layer : layers) {
+                getSource().checkContainsLayer(layer);
+            }
+            scheduleForRemoval.addAll(layers);
         }
 
@@ -198,8 +217,23 @@
 
     protected synchronized void realRemoveLayer(Layer layer) {
-        checkContainsLayer(layer);
-
-        fireLayerRemoving(layer);
-        layers.remove(layer);
+        GuiHelper.assertCallFromEdt();
+        Set<Layer> toRemove = Collections.newSetFromMap(new IdentityHashMap<Layer, Boolean>());
+        toRemove.add(layer);
+
+        while (!toRemove.isEmpty()) {
+            Iterator<Layer> iterator = toRemove.iterator();
+            Layer layerToRemove = iterator.next();
+            iterator.remove();
+            checkContainsLayer(layerToRemove);
+
+            Collection<Layer> newToRemove = realRemoveSingleLayer(layerToRemove);
+            toRemove.addAll(newToRemove);
+        }
+    }
+
+    protected Collection<Layer> realRemoveSingleLayer(Layer layerToRemove) {
+        Collection<Layer> newToRemove = fireLayerRemoving(layerToRemove);
+        layers.remove(layerToRemove);
+        return newToRemove;
     }
 
@@ -334,10 +368,10 @@
     }
 
-
     /**
      * Removes a layer change listener
      *
      * @param listener the listener.
-     * @param fireRemove if we should fire a remove event for every layer in this manager.
+     * @param fireRemove if we should fire a remove event for every layer in this manager. The event is fired as if the layer was deleted but
+     * {@link LayerRemoveEvent#scheduleRemoval(Collection)} is ignored.
      */
     public synchronized void removeLayerChangeListener(LayerChangeListener listener, boolean fireRemove) {
@@ -365,5 +399,10 @@
     }
 
-    private void fireLayerRemoving(Layer layer) {
+    /**
+     * Fire the layer remove event
+     * @param layer The layer to remove
+     * @return A list of layers that should be removed afterwards.
+     */
+    private Collection<Layer> fireLayerRemoving(Layer layer) {
         GuiHelper.assertCallFromEdt();
         LayerRemoveEvent e = new LayerRemoveEvent(this, layer);
@@ -372,7 +411,8 @@
                 l.layerRemoving(e);
             } catch (RuntimeException t) {
-                throw BugReport.intercept(t).put("listener", l).put("event", e);
-            }
-        }
+                throw BugReport.intercept(t).put("listener", l).put("event", e).put("layer", layer);
+            }
+        }
+        return e.scheduleForRemoval;
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java	(revision 10506)
+++ trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java	(revision 10507)
@@ -3,4 +3,5 @@
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.ListIterator;
@@ -207,5 +208,5 @@
 
     @Override
-    protected synchronized void realRemoveLayer(Layer layer) {
+    protected Collection<Layer> realRemoveSingleLayer(Layer layer) {
         if (layer == activeLayer || layer == editLayer) {
             Layer nextActive = suggestNextActiveLayer(layer);
@@ -213,5 +214,5 @@
         }
 
-        super.realRemoveLayer(layer);
+        return super.realRemoveSingleLayer(layer);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/ValidatorLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/ValidatorLayer.java	(revision 10506)
+++ trunk/src/org/openstreetmap/josm/gui/layer/ValidatorLayer.java	(revision 10507)
@@ -5,4 +5,5 @@
 
 import java.awt.Graphics2D;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.List;
@@ -165,5 +166,5 @@
         // Removed layer is still in that list.
         if (e.getRemovedLayer() instanceof OsmDataLayer && e.getSource().getLayersOfType(OsmDataLayer.class).size() <= 1) {
-            Main.getLayerManager().removeLayer(this);
+            e.scheduleRemoval(Collections.singleton(this));
         } else if (e.getRemovedLayer() == this) {
             Main.getLayerManager().removeLayerChangeListener(this);
