Index: applications/editors/josm/plugins/imagery_offset_db/build.xml
===================================================================
--- applications/editors/josm/plugins/imagery_offset_db/build.xml	(revision 29409)
+++ applications/editors/josm/plugins/imagery_offset_db/build.xml	(revision 29412)
@@ -32,5 +32,5 @@
     <property name="commit.message" value="Imagery Offset Database"/>
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-    <property name="plugin.main.version" value="4549"/>
+    <property name="plugin.main.version" value="4666"/>
     <!--
       ************************************************
Index: applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetPlugin.java
===================================================================
--- applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetPlugin.java	(revision 29409)
+++ applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetPlugin.java	(revision 29412)
@@ -5,4 +5,5 @@
 import javax.swing.JMenu;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Version;
 import org.openstreetmap.josm.plugins.Plugin;
 import org.openstreetmap.josm.plugins.PluginInformation;
@@ -31,15 +32,24 @@
         storeAction = new StoreImageryOffsetAction();
         
-        JMenu offsetMenu = Main.main.menu.addMenu(marktr("Offset"), KeyEvent.VK_O, 6, "help");
+        // before 5803 imagery menu was constantly regenerated, erasing extra items
+        // before 5729 it was regenerated only when the imagery list was modified (also bad)
+        int version = Version.getInstance().getVersion();
+        JMenu offsetMenu = version < 5803
+                ? Main.main.menu.addMenu(marktr("Offset"), KeyEvent.VK_O, 6, "help")
+                : Main.main.menu.imageryMenu;
         offsetMenu.add(getAction);
         offsetMenu.add(storeAction);
+        if( version >= 5803 ) // todo: check if this is needed
+            offsetMenu.addSeparator();
 
         // an ugly hack to add this plugin to the toolbar
-        Collection<String> toolbar = new LinkedList<String>(Main.toolbar.getToolString());
-        if( !toolbar.contains("getoffset") && Main.pref.getBoolean("iodb.modify.toolbar", true) ) {
-            toolbar.add("getoffset");
-            Main.pref.putCollection("toolbar", toolbar);
+        if( Main.pref.getBoolean("iodb.modify.toolbar", true) ) {
+            Collection<String> toolbar = new LinkedList<String>(Main.toolbar.getToolString());
+            if( !toolbar.contains("getoffset") ) {
+                toolbar.add("getoffset");
+                Main.pref.putCollection("toolbar", toolbar);
+                Main.toolbar.refreshToolbarControl();
+            }
             Main.pref.put("iodb.modify.toolbar", false);
-            Main.toolbar.refreshToolbarControl();
         }
     }
Index: applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetWatcher.java
===================================================================
--- applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetWatcher.java	(revision 29409)
+++ applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetWatcher.java	(revision 29412)
@@ -7,4 +7,5 @@
 import org.openstreetmap.josm.gui.layer.ImageryLayer;
 import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.tools.Destroyable;
 
 /**
@@ -15,5 +16,5 @@
  * @license WTFPL
  */
-public class ImageryOffsetWatcher implements MapView.ZoomChangeListener, MapView.LayerChangeListener {
+public class ImageryOffsetWatcher implements MapView.ZoomChangeListener, MapView.LayerChangeListener, Destroyable {
     private static final double THRESHOLD = 1e-8;
     private static ImageryOffsetWatcher instance;
@@ -118,4 +119,5 @@
                 data.lastDy = layer.getDy();
                 data.lastChecked = center;
+                storeLayerOffset(layer);
                 setOffsetGood(true);
             } else {
@@ -125,4 +127,9 @@
     }
 
+    /**
+     * Mark the current offset as good. This method is called by {@link OffsetDialog}
+     * to notify the watcher that an offset button has been clicked, and regardless of
+     * whether it has changed an offset, the currect imagery alignment is ok.
+     */
     public void markGood() {
         ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer();
@@ -143,4 +150,5 @@
                 data.lastChecked = center;
             }
+            storeLayerOffset(layer);
         }
         setOffsetGood(true);
@@ -166,4 +174,6 @@
 
     public void layerAdded( Layer newLayer ) {
+        if( newLayer instanceof ImageryLayer )
+            loadLayerOffset((ImageryLayer)newLayer);
         checkOffset();
     }
@@ -171,4 +181,52 @@
     public void layerRemoved( Layer oldLayer ) {
         checkOffset();
+    }
+
+    /**
+     * Saves the current imagery layer offset to preferences. It is stored as a
+     * collection of ':'-separated strings: imagery_id:lat:lon:dx:dy. No need for
+     * projections: nobody uses them anyway.
+     */
+    private void storeLayerOffset( ImageryLayer layer ) {
+        String id = ImageryOffsetTools.getImageryID(layer);
+        if( !Main.pref.getBoolean("iodb.remember.offsets", true) || id == null )
+            return;
+        Collection<String> offsets = new LinkedList<String>(Main.pref.getCollection("iodb.stored.offsets"));
+        for( Iterator<String> iter = offsets.iterator(); iter.hasNext(); ) {
+            String[] offset = iter.next().split(":");
+            if( offset.length == 5 && offset[0].equals(id) )
+                iter.remove();
+        }
+        LatLon center = ImageryOffsetTools.getMapCenter();
+        offsets.add(id + ":" + center.lat() + ":" + center.lon() + ":" + layer.getDx() + ":" + layer.getDy());
+        Main.pref.putCollection("iodb.stored.offsets", offsets);
+    }
+
+    /**
+     * Loads the current imagery layer offset from preferences. 
+     */
+    private void loadLayerOffset( ImageryLayer layer ) {
+        String id = ImageryOffsetTools.getImageryID(layer);
+        if( !Main.pref.getBoolean("iodb.remember.offsets", true) || id == null )
+            return;
+        Collection<String> offsets = Main.pref.getCollection("iodb.stored.offsets");
+        for( String offset : offsets ) {
+            String[] parts = offset.split(":");
+            if( parts.length == 5 && parts[0].equals(id) ) {
+                double[] dparts = new double[4];
+                try {
+                    for( int i = 0; i < 4; i++ )
+                        dparts[i] = Double.parseDouble(parts[i+1]);
+                } catch( Exception e ) {
+                    continue;
+                }
+                LatLon lastPos = new LatLon(dparts[0], dparts[1]);
+                if( lastPos.greatCircleDistance(ImageryOffsetTools.getMapCenter()) < Math.max(maxDistance, 3.0) * 1000 ) {
+                    // apply offset
+                    layer.setOffset(dparts[2], dparts[3]);
+                    return;
+                }
+            }
+        }
     }
 
Index: applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialog.java
===================================================================
--- applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialog.java	(revision 29409)
+++ applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialog.java	(revision 29412)
@@ -31,5 +31,5 @@
     protected static final String PREF_CALIBRATION = "iodb.show.calibration";
     protected static final String PREF_DEPRECATED = "iodb.show.deprecated";
-    private static final int MAX_OFFSETS = Main.main.pref.getInteger("iodb.max.offsets", 5);
+    private static final int MAX_OFFSETS = Main.main.pref.getInteger("iodb.max.offsets", 4);
 
     /**
