diff --git a/src/org/openstreetmap/josm/actions/mapmode/MapMode.java b/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
index f6d774f..b4418be 100644
--- a/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
+++ b/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
@@ -10,12 +10,12 @@ import java.awt.event.MouseMotionListener;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
+import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Shortcut;
-import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
-import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
 
 /**
  * A class implementing MapMode is able to be selected as an mode for map editing.
@@ -56,11 +56,14 @@ public abstract class MapMode extends JosmAction implements MouseListener, Mouse
         putValue(NAME, name);
         putValue(SMALL_ICON, ImageProvider.get("mapmode", iconName));
         putValue(SHORT_DESCRIPTION, tooltip);
+        putValue("active", Boolean.FALSE);
         this.cursor = cursor;
     }
 
     /**
-     * Makes this map mode active.
+     * Makes this map mode active. This may never fail. Super needs to be called if implementations override this method.
+     * <p>
+     * Use {@link #layerIsSupported(Layer)} to prevent the mode from being activated.
      */
     public void enterMode() {
         putValue("active", Boolean.TRUE);
@@ -71,7 +74,20 @@ public abstract class MapMode extends JosmAction implements MouseListener, Mouse
     }
 
     /**
-     * Makes this map mode inactive.
+     * Calls {@link #enterMode()}. Checks the state.
+     */
+    public final void enterModeCallCheck() {
+        if (getValue("active") != Boolean.FALSE) {
+            throw new IllegalStateException("enterMode() called twice");
+        }
+        enterMode();
+        if (getValue("active") != Boolean.TRUE) {
+            throw new IllegalStateException("enterMode() did not call super.");
+        }
+    }
+
+    /**
+     * Makes this map mode inactive. This may never fail. Super needs to be called if implementations override this method.
      */
     public void exitMode() {
         putValue("active", Boolean.FALSE);
@@ -79,6 +95,19 @@ public abstract class MapMode extends JosmAction implements MouseListener, Mouse
         Main.map.mapView.resetCursor(this);
     }
 
+    /**
+     * Calls {@link #exitMode()}. Checks the state.
+     */
+    public final void exitModeCallCheck() {
+        if (getValue("active") != Boolean.TRUE) {
+            throw new IllegalStateException("exitMode() called twice");
+        }
+        exitMode();
+        if (getValue("active") != Boolean.FALSE) {
+            throw new IllegalStateException("exitMode() did not call super.");
+        }
+    }
+
     protected void updateStatusLine() {
         Main.map.statusLine.setHelpText(getModeHelpText());
         Main.map.statusLine.repaint();
diff --git a/src/org/openstreetmap/josm/gui/MapFrame.java b/src/org/openstreetmap/josm/gui/MapFrame.java
index 9a12018..2dc64c6 100644
--- a/src/org/openstreetmap/josm/gui/MapFrame.java
+++ b/src/org/openstreetmap/josm/gui/MapFrame.java
@@ -447,10 +447,10 @@ public class MapFrame extends JPanel implements Destroyable, ActiveLayerChangeLi
         if (newMapMode == oldMapMode)
             return true;
         if (oldMapMode != null) {
-            oldMapMode.exitMode();
+            oldMapMode.exitModeCallCheck();
         }
         this.mapMode = newMapMode;
-        newMapMode.enterMode();
+        newMapMode.enterModeCallCheck();
         lastMapMode.put(newLayer, newMapMode);
         fireMapModeChanged(oldMapMode, newMapMode);
         return true;
@@ -774,7 +774,7 @@ public class MapFrame extends JPanel implements Destroyable, ActiveLayerChangeLi
                 // but it don't work well with for example editgpx layer
                 selectMapMode(newMapMode, newLayer);
             } else if (mapMode != null) {
-                mapMode.exitMode(); // if new mode is null - simply exit from previous mode
+                mapMode.exitModeCallCheck(); // if new mode is null - simply exit from previous mode
                 mapMode = null;
             }
         }
@@ -782,8 +782,8 @@ public class MapFrame extends JPanel implements Destroyable, ActiveLayerChangeLi
         if (e.getPreviousActiveLayer() != null) {
             if (!modeChanged && mapMode != null) {
                 // Let mapmodes know about new active layer
-                mapMode.exitMode();
-                mapMode.enterMode();
+                mapMode.exitModeCallCheck();
+                mapMode.enterModeCallCheck();
             }
             // invalidate repaint cache
             mapView.preferenceChanged(null);
