Index: trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java	(revision 5504)
+++ trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java	(revision 5505)
@@ -79,5 +79,5 @@
 
         JFileChooser fc;
-        
+
         if (zipRequired) {
             fc = createAndOpenFileChooser(false, false, tr("Save session"), joz, JFileChooser.FILES_ONLY, "lastDirectory");
@@ -109,7 +109,7 @@
         if (fn.indexOf('.') == -1) {
             file = new File(file.getPath() + (zip ? ".joz" : ".jos"));
-        }
-        if (!SaveActionBase.confirmOverwrite(file))
-            return;
+            if (!SaveActionBase.confirmOverwrite(file))
+                return;
+        }
 
         List<Layer> layersOut = new ArrayList<Layer>();
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 5504)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 5505)
@@ -238,11 +238,4 @@
             if (layer != null) {
                 Main.main.addLayer(layer);
-                layer.hook_up_mouse_events(); // Main.map.mapView should exist
-                // now. Can add mouse listener
-                Main.map.mapView.addPropertyChangeListener(layer);
-                if (Main.map.getToggleDialog(ImageViewerDialog.class) == null) {
-                    ImageViewerDialog.newInstance();
-                    Main.map.addToggleDialog(ImageViewerDialog.getInstance());
-                }
 
                 if (! canceled && layer.data.size() > 0) {
@@ -270,5 +263,5 @@
     }
 
-    private GeoImageLayer(final List<ImageEntry> data, GpxLayer gpxLayer) {
+    public GeoImageLayer(final List<ImageEntry> data, GpxLayer gpxLayer) {
 
         super(tr("Geotagged Images"));
@@ -723,5 +716,6 @@
     private MapModeChangeListener mapModeListener = null;
 
-    private void hook_up_mouse_events() {
+    @Override
+    public void hookUpMapView() {
         mouseAdapter = new MouseAdapter() {
             private final boolean isMapModeOk() {
@@ -808,4 +802,10 @@
             }
         });
+
+        Main.map.mapView.addPropertyChangeListener(this);
+        if (Main.map.getToggleDialog(ImageViewerDialog.class) == null) {
+            ImageViewerDialog.newInstance();
+            Main.map.addToggleDialog(ImageViewerDialog.getInstance());
+        }
     }
 
@@ -839,4 +839,8 @@
     }
 
+    public GpxLayer getGpxLayer() {
+        return gpxLayer;
+    }
+
     public void jumpToNextMarker() {
         showNextPhoto();
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java	(revision 5504)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java	(revision 5505)
@@ -80,9 +80,13 @@
         return exifTime;
     }
-    LatLon getExifCoor() {
+    public LatLon getExifCoor() {
         return exifCoor;
     }
     public Double getExifImgDir() {
         return exifImgDir;
+    }
+
+    public boolean hasThumbnail() {
+        return thumbnail != null;
     }
 
@@ -102,20 +106,20 @@
         this.elevation = elevation;
     }
-    void setFile(File file) {
+    public void setFile(File file) {
         this.file = file;
     }
-    void setExifOrientation(Integer exifOrientation) {
+    public void setExifOrientation(Integer exifOrientation) {
         this.exifOrientation = exifOrientation;
     }
-    void setExifTime(Date exifTime) {
+    public void setExifTime(Date exifTime) {
         this.exifTime = exifTime;
     }
-    void setGpsTime(Date gpsTime) {
+    public void setGpsTime(Date gpsTime) {
         this.gpsTime = gpsTime;
     }
-    void setExifCoor(LatLon exifCoor) {
+    public void setExifCoor(LatLon exifCoor) {
         this.exifCoor = exifCoor;
     }
-    void setExifImgDir(double exifDir) {
+    public void setExifImgDir(double exifDir) {
         this.exifImgDir = exifDir;
     }
Index: trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionExporter.java	(revision 5505)
+++ trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionExporter.java	(revision 5505)
@@ -0,0 +1,123 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.session;
+
+import java.awt.Component;
+import java.awt.GridBagLayout;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
+import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry;
+import org.openstreetmap.josm.tools.GBC;
+import org.w3c.dom.Element;
+
+public class GeoImageSessionExporter implements SessionLayerExporter {
+
+    private GeoImageLayer layer;
+
+    public GeoImageSessionExporter(GeoImageLayer layer) {
+        this.layer = layer;
+    }
+
+    private JCheckBox export;
+
+    @Override
+    public Collection<Layer> getDependencies() {
+        if (layer.getGpxLayer() != null)
+            return Collections.singleton((Layer) layer.getGpxLayer());
+        else
+            return Collections.emptySet();
+    }
+
+    @Override
+    public Component getExportPanel() {
+        final JPanel p = new JPanel(new GridBagLayout());
+        export = new JCheckBox();
+        export.setSelected(true);
+        final JLabel lbl = new JLabel(layer.getName(), layer.getIcon(), SwingConstants.LEFT);
+        lbl.setToolTipText(layer.getToolTipText());
+        p.add(export, GBC.std());
+        p.add(lbl, GBC.std());
+        p.add(GBC.glue(1,0), GBC.std().fill(GBC.HORIZONTAL));
+        return p;
+    }
+
+    @Override
+    public boolean shallExport() {
+        return export.isSelected();
+    }
+
+    @Override
+    public boolean requiresZip() {
+        return false;
+    }
+
+    @Override
+    public Element export(SessionWriter.ExportSupport support) throws IOException {
+        Element layerElem = support.createElement("layer");
+        layerElem.setAttribute("type", "geoimage");
+        layerElem.setAttribute("version", "0.1");
+
+        for (ImageEntry entry : layer.getImages()) {
+            
+            Element imgElem = support.createElement("geoimage");
+
+            if (entry.getFile() == null) {
+                Main.warn("No file attribute for image - skipping entry");
+                break;
+            }
+            addAttr("file", entry.getFile().getPath(), imgElem, support);
+            // FIXME: relative filenames as option
+            // FIXME: include images as option (?)
+
+            addAttr("thumbnail", Boolean.toString(entry.hasThumbnail()), imgElem, support);
+            if (entry.getPos() != null) {
+                Element posElem = support.createElement("position");
+                posElem.setAttribute("lat", Double.toString(entry.getPos().lat()));
+                posElem.setAttribute("lon", Double.toString(entry.getPos().lon()));
+                imgElem.appendChild(posElem);
+            }
+            if (entry.getSpeed() != null) {
+                addAttr("speed", entry.getSpeed().toString(), imgElem, support);
+            }
+            if (entry.getElevation() != null) {
+                addAttr("elevation", entry.getElevation().toString(), imgElem, support);
+            }
+            if (entry.getGpsTime() != null) {
+                addAttr("gps-time", Long.toString(entry.getGpsTime().getTime()), imgElem, support);
+            }
+            if (entry.getExifOrientation() != null) {
+                addAttr("exif-orientation", Integer.toString(entry.getExifOrientation()), imgElem, support);
+            }
+            if (entry.getExifTime() != null) {
+                addAttr("exif-time", Long.toString(entry.getExifTime().getTime()), imgElem, support);
+            }
+            if (entry.getExifCoor() != null) {
+                Element posElem = support.createElement("exif-coordinates");
+                posElem.setAttribute("lat", Double.toString(entry.getExifCoor().lat()));
+                posElem.setAttribute("lon", Double.toString(entry.getExifCoor().lon()));
+                imgElem.appendChild(posElem);
+            }
+            if (entry.getExifImgDir() != null) {
+                addAttr("exif-image-direction", entry.getExifImgDir().toString(), imgElem, support);
+            }
+
+            layerElem.appendChild(imgElem);
+        }
+        return layerElem;
+    }
+
+    private void addAttr(String name, String value, Element element, SessionWriter.ExportSupport support) {
+            Element attrElem = support.createElement(name);
+            attrElem.appendChild(support.createTextNode(value));
+            element.appendChild(attrElem);
+    }
+}
Index: trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java	(revision 5505)
+++ trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java	(revision 5505)
@@ -0,0 +1,99 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.session;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.openstreetmap.josm.data.Preferences;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.imagery.ImageryInfo;
+import org.openstreetmap.josm.gui.layer.GpxLayer;
+import org.openstreetmap.josm.gui.layer.ImageryLayer;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
+import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class GeoImageSessionImporter implements SessionLayerImporter {
+
+    @Override
+    public Layer load(Element elem, SessionReader.ImportSupport support, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
+        String version = elem.getAttribute("version");
+        if (!"0.1".equals(version)) {
+            throw new IllegalDataException(tr("Version ''{0}'' of meta data for geoimage layer is not supported. Expected: 0.1", version));
+        }
+
+        List<ImageEntry> entries = new ArrayList<ImageEntry>();
+        NodeList imgNodes = elem.getChildNodes();
+        for (int i=0; i<imgNodes.getLength(); ++i) {
+            Node imgNode = imgNodes.item(i);
+            if (imgNode.getNodeType() == Node.ELEMENT_NODE) {
+                Element imgElem = (Element) imgNode;
+                if (imgElem.getTagName().equals("geoimage")) {
+                    ImageEntry entry = new ImageEntry();
+                    NodeList attrNodes = imgElem.getChildNodes();
+                    for (int j=0; j<attrNodes.getLength(); ++j) {
+                        Node attrNode = attrNodes.item(j);
+                        if (attrNode.getNodeType() == Node.ELEMENT_NODE) {
+                            Element attrElem = (Element) attrNode;
+                            try {
+                                if (attrElem.getTagName().equals("file")) {
+                                    entry.setFile(new File(attrElem.getTextContent()));
+                                } else if (attrElem.getTagName().equals("position")) {
+                                    double lat = Double.parseDouble(attrElem.getAttribute("lat"));
+                                    double lon = Double.parseDouble(attrElem.getAttribute("lon"));
+                                    entry.setPos(new LatLon(lat, lon));
+                                } else if (attrElem.getTagName().equals("speed")) {
+                                    entry.setSpeed(Double.parseDouble(attrElem.getTextContent()));
+                                } else if (attrElem.getTagName().equals("elevation")) {
+                                    entry.setElevation(Double.parseDouble(attrElem.getTextContent()));
+                                } else if (attrElem.getTagName().equals("gps-time")) {
+                                    entry.setGpsTime(new Date(Long.parseLong(attrElem.getTextContent())));
+                                } else if (attrElem.getTagName().equals("gps-orientation")) {
+                                    entry.setExifOrientation(Integer.parseInt(attrElem.getTextContent()));
+                                } else if (attrElem.getTagName().equals("exif-time")) {
+                                    entry.setExifTime(new Date(Long.parseLong(attrElem.getTextContent())));
+                                } else if (attrElem.getTagName().equals("exif-coordinates")) {
+                                    double lat = Double.parseDouble(attrElem.getAttribute("lat"));
+                                    double lon = Double.parseDouble(attrElem.getAttribute("lon"));
+                                    entry.setExifCoor(new LatLon(lat, lon));
+                                } else if (attrElem.getTagName().equals("exif-image-direction")) {
+                                    entry.setExifImgDir(Double.parseDouble(attrElem.getTextContent()));
+                                }
+                                // TODO: handle thumbnail loading
+                            } catch (NumberFormatException e) {
+                                // nothing
+                            }
+                        }
+                    }
+                    entries.add(entry);
+                }
+            }
+        }
+
+        GpxLayer gpxLayer = null;
+        List<SessionReader.LayerDependency> deps = support.getLayerDependencies();
+        if (deps.size() > 0) {
+            Layer layer = deps.iterator().next().getLayer();
+            if (layer instanceof GpxLayer) {
+                gpxLayer = (GpxLayer) layer;
+            }
+        }
+        
+        return new GeoImageLayer(entries, gpxLayer);
+    }
+
+
+
+}
Index: trunk/src/org/openstreetmap/josm/io/session/SessionReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 5504)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 5505)
@@ -58,4 +58,5 @@
         registerSessionLayerImporter("imagery", ImagerySessionImporter.class);
         registerSessionLayerImporter("tracks", GpxTracksSessionImporter.class);
+        registerSessionLayerImporter("geoimage", GeoImageSessionImporter.class);
     }
 
@@ -103,7 +104,7 @@
         private String layerName;
         private int layerIndex;
-        private LinkedHashMap<Integer,SessionLayerImporter> layerDependencies;
-
-        public ImportSupport(String layerName, int layerIndex, LinkedHashMap<Integer,SessionLayerImporter> layerDependencies) {
+        private List<LayerDependency> layerDependencies;
+
+        public ImportSupport(String layerName, int layerIndex, List<LayerDependency> layerDependencies) {
             this.layerName = layerName;
             this.layerIndex = layerIndex;
@@ -234,6 +235,30 @@
          * layer. All the dependent importers have loaded completely at this point.
          */
-        public LinkedHashMap<Integer,SessionLayerImporter> getLayerDependencies() {
+        public List<LayerDependency> getLayerDependencies() {
             return layerDependencies;
+        }
+    }
+
+    public static class LayerDependency {
+        private Integer index;
+        private Layer layer;
+        private SessionLayerImporter importer;
+
+        public LayerDependency(Integer index, Layer layer, SessionLayerImporter importer) {
+            this.index = index;
+            this.layer = layer;
+            this.importer = importer;
+        }
+
+        public SessionLayerImporter getImporter() {
+            return importer;
+        }
+
+        public Integer getIndex() {
+            return index;
+        }
+
+        public Layer getLayer() {
+            return layer;
         }
     }
@@ -338,5 +363,5 @@
             } else {
                 importers.put(idx, imp);
-                LinkedHashMap<Integer,SessionLayerImporter> depsImp = new LinkedHashMap<Integer,SessionLayerImporter>();
+                List<LayerDependency> depsImp = new ArrayList<LayerDependency>();
                 for (int d : deps.get(idx)) {
                     SessionLayerImporter dImp = importers.get(d);
@@ -356,5 +381,5 @@
                         }
                     }
-                    depsImp.put(d, dImp);
+                    depsImp.add(new LayerDependency(d, layersMap.get(d), dImp));
                 }
                 ImportSupport support = new ImportSupport(name, idx, depsImp);
Index: trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 5504)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 5505)
@@ -33,4 +33,5 @@
 import org.openstreetmap.josm.gui.layer.TMSLayer;
 import org.openstreetmap.josm.gui.layer.WMSLayer;
+import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
@@ -48,4 +49,5 @@
         registerSessionLayerExporter(WMSLayer.class , ImagerySessionExporter.class);
         registerSessionLayerExporter(GpxLayer.class , GpxTracksSessionExporter.class);
+        registerSessionLayerExporter(GeoImageLayer.class , GeoImageSessionExporter.class);
     }
 
