Index: trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java	(revision 5684)
@@ -14,5 +14,4 @@
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -64,5 +63,5 @@
         SessionSaveAsDialog dlg = new SessionSaveAsDialog();
         dlg.showDialog();
-        if (dlg.getValue() != 2) return;
+        if (dlg.getValue() != 1) return;
 
         zipRequired = false;
@@ -138,8 +137,8 @@
 
         public SessionSaveAsDialog() {
-            super(Main.parent, tr("Save Session"), new String[] {tr("Cancel"), tr("Save As")});
+            super(Main.parent, tr("Save Session"), new String[] {tr("Save As"), tr("Cancel")});
             initialize();
-            setButtonIcons(new String[] {"cancel", "save_as"});
-            setDefaultButton(2);
+            setButtonIcons(new String[] {"save_as", "cancel"});
+            setDefaultButton(1);
             setRememberWindowGeometry(getClass().getName() + ".geometry",
                     WindowGeometry.centerInWindow(Main.parent, new Dimension(350, 450)));
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java	(revision 5684)
@@ -28,5 +28,5 @@
     public static List<String> WPT_KEYS = Arrays.asList("ele", "time", "magvar", "geoidheight",
             "name", "cmt", "desc", "src", META_LINKS, "sym", "number", "type",
-            "fix", "sat", "hdop", "vdop", "pdop", "ageofdgpsdata", "dgpsid");
+            "fix", "sat", "hdop", "vdop", "pdop", "ageofdgpsdata", "dgpsid", META_EXTENSIONS);
 
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/IWithAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/IWithAttributes.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/data/gpx/IWithAttributes.java	(revision 5684)
@@ -5,7 +5,16 @@
 
 /**
- * Object with attributes.
+ * Object with attributes (in the context of GPX data).
  */
 public interface IWithAttributes {
+
+    /**
+     * Returns the Object value to which the specified key is mapped,
+     * or {@code null} if this map contains no mapping for the key.
+     *
+     * @param key the key whose associated value is to be returned
+     * @return the value
+     */
+    Object get(String key);
 
     /**
@@ -18,14 +27,33 @@
      */
     String getString(String key);
-    
+
     /**
-     * Returns the Collection value to which the specified key is mapped, 
+     * Returns the Collection value to which the specified key is mapped,
      * or {@code null} if this map contains no Collection mapping for the key.
-     *  
+     *
      * @param key the key whose associated value is to be returned
-     * @return the Collection value to which the specified key is mapped, 
+     * @return the Collection value to which the specified key is mapped,
      *         or {@code null} if this map contains no Collection mapping for the key
      * @since 5502
      */
-    Collection<?> getCollection(String key);
+    Collection getCollection(String key);
+
+    /**
+     * Put a key / value pair as a new attribute.
+     *
+     * Overrides key / value pair with the same key (if present).
+     *
+     * @param key the key
+     * @param value the value
+     */
+    void put(String key, Object value);
+
+    /**
+     * Add a key / value pair that is not part of the GPX schema as an extension.
+     *
+     * @param key the key
+     * @param value the value
+     */
+    void addExtension(String key, String value);
+
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java	(revision 5684)
@@ -20,4 +20,16 @@
      */
     public Map<String, Object> attr = new HashMap<String, Object>(0);
+
+    /**
+     * Returns the Object value to which the specified key is mapped,
+     * or {@code null} if this map contains no mapping for the key.
+     *
+     * @param key the key whose associated value is to be returned
+     * @return the value
+     */
+    @Override
+    public Object get(String key) {
+        return attr.get(key);
+    }
 
     /**
@@ -45,7 +57,35 @@
      */
     @Override
-    public Collection<?> getCollection(String key) {
+    public Collection getCollection(String key) {
         Object value = attr.get(key);
-        return (value instanceof Collection<?>) ? (Collection<?>)value : null;
+        return (value instanceof Collection) ? (Collection)value : null;
+    }
+
+    /**
+     * Put a key / value pair as a new attribute.
+     *
+     * Overrides key / value pair with the same key (if present).
+     *
+     * @param key the key
+     * @param value the value
+     */
+    @Override
+    public void put(String key, Object value) {
+        attr.put(key, value);
+    }
+
+    /**
+     * Add a key / value pair that is not part of the GPX schema as an extension.
+     *
+     * @param key the key
+     * @param value the value
+     */
+    @Override
+    public void addExtension(String key, String value) {
+        if (!attr.containsKey(META_EXTENSIONS)) {
+            attr.put(META_EXTENSIONS, new Extensions());
+        }
+        Extensions ext = (Extensions) attr.get(META_EXTENSIONS);
+        ext.put(key, value);
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/AudioMarker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/AudioMarker.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/AudioMarker.java	(revision 5684)
@@ -4,7 +4,11 @@
 import java.awt.event.ActionEvent;
 import java.net.URL;
+import java.util.Collections;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
+import org.openstreetmap.josm.data.gpx.GpxLink;
+import org.openstreetmap.josm.data.gpx.WayPoint;
 import org.openstreetmap.josm.tools.AudioPlayer;
 import org.openstreetmap.josm.tools.template_engine.TemplateEngineDataProvider;
@@ -77,3 +81,14 @@
         return TemplateEntryProperty.forAudioMarker(parentLayer.getName());
     }
+
+    @Override
+    public WayPoint convertToWayPoint() {
+        WayPoint wpt = super.convertToWayPoint();
+        GpxLink link = new GpxLink(audioUrl.toString());
+        link.type = "audio";
+        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
+        wpt.addExtension("offset", Double.toString(offset));
+        wpt.addExtension("sync-offset", Double.toString(syncOffset));
+        return wpt;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ImageMarker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ImageMarker.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ImageMarker.java	(revision 5684)
@@ -8,4 +8,5 @@
 import java.awt.event.ActionListener;
 import java.net.URL;
+import java.util.Collections;
 
 import javax.swing.Icon;
@@ -21,4 +22,7 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
+import org.openstreetmap.josm.data.gpx.GpxLink;
+import org.openstreetmap.josm.data.gpx.WayPoint;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -83,3 +87,12 @@
     }
 
+    @Override
+    public WayPoint convertToWayPoint() {
+        WayPoint wpt = super.convertToWayPoint();
+        GpxLink link = new GpxLink(imageUrl.toString());
+        link.type = "image";
+        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
+        return wpt;
+    }
+
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 5684)
@@ -8,10 +8,14 @@
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.TimeZone;
 
 import javax.swing.Icon;
@@ -23,4 +27,5 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.Extensions;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxLink;
@@ -181,4 +186,5 @@
         Marker.markerProducers.add(new MarkerProducers() {
             @SuppressWarnings("unchecked")
+            @Override
             public Marker createMarker(WayPoint wpt, File relativePath, MarkerLayer parentLayer, double time, double offset) {
                 String uri = null;
@@ -217,5 +223,13 @@
                 }
                 else if (url.toString().endsWith(".wav")) {
-                    return new AudioMarker(wpt.getCoor(), wpt, url, parentLayer, time, offset);
+                    AudioMarker audioMarker = new AudioMarker(wpt.getCoor(), wpt, url, parentLayer, time, offset);
+                    Extensions exts = (Extensions) wpt.get(GpxConstants.META_EXTENSIONS);
+                    if (exts != null && exts.containsKey("offset")) {
+                        try {
+                            double syncOffset = Double.parseDouble(exts.get("sync-offset"));
+                            audioMarker.syncOffset = syncOffset;
+                        } catch (NumberFormatException nfe) {}
+                    }
+                    return audioMarker;
                 } else if (url.toString().endsWith(".png") || url.toString().endsWith(".jpg") || url.toString().endsWith(".jpeg") || url.toString().endsWith(".gif")) {
                     return new ImageMarker(wpt.getCoor(), url, parentLayer, time, offset);
@@ -234,4 +248,6 @@
      * @param relativePath An path to use for constructing relative URLs or
      *        <code>null</code> for no relative URLs
+     * @param parentLayer the <code>MarkerLayer</code> that will contain the created <code>Marker</code>
+     * @param time time of the marker in seconds since epoch
      * @param offset double in seconds as the time offset of this marker from
      *        the GPX file from which it was derived (if any).
@@ -247,4 +263,10 @@
     }
 
+    private static final DateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+    static {
+         TimeZone tz = TimeZone.getTimeZone("UTC");
+         timeFormatter.setTimeZone(tz);
+    }
+
     public static final String MARKER_OFFSET = "waypointOffset";
     public static final String MARKER_FORMATTED_OFFSET = "formattedWaypointOffset";
@@ -254,5 +276,4 @@
     public static final String LABEL_PATTERN_DESC = "{desc}";
 
-
     private final TemplateEngineDataProvider dataProvider;
     private final String text;
@@ -260,5 +281,5 @@
     public final Icon symbol;
     public final MarkerLayer parentLayer;
-    public double time; /* absolute time of marker since epoch */
+    public double time; /* absolute time of marker in seconds since epoch */
     public double offset; /* time offset in seconds from the gpx point from which it was derived,
                              may be adjusted later to sync with other data, so not final */
@@ -296,4 +317,27 @@
     }
 
+    /**
+     * Convert Marker to WayPoint so it can be exported to a GPX file.
+     *
+     * Override in subclasses to add all necessary attributes.
+     * 
+     * @return the corresponding WayPoint with all relevant attributes
+     */
+    public WayPoint convertToWayPoint() {
+        WayPoint wpt = new WayPoint(getCoor());
+        wpt.put("time", timeFormatter.format(new Date(Math.round(time * 1000))));
+        if (text != null) {
+            wpt.addExtension("text", text);
+        } else if (dataProvider != null) {
+            for (String key : dataProvider.getTemplateKeys()) {
+                Object value = dataProvider.getTemplateValue(key, false);
+                if (value != null && GpxConstants.WPT_KEYS.contains(key)) {
+                    wpt.put(key, value);
+                }
+            }
+        }
+        return wpt;
+    }
+
     public final void setCoor(LatLon coor) {
         if(this.coor == null) {
@@ -343,4 +387,5 @@
      * @param mv map view
      * @param mousePressed true if the left mouse button is pressed
+     * @param showTextOrIcon true if text and icon shall be drawn
      */
     public void paint(Graphics g, MapView mv, boolean mousePressed, boolean showTextOrIcon) {
@@ -398,5 +443,5 @@
     }
 
-    private String formatOffset () {
+    private String formatOffset() {
         int wholeSeconds = (int)(offset + 0.5);
         if (wholeSeconds < 60)
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 5684)
@@ -32,4 +32,5 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.Extensions;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
@@ -108,5 +109,20 @@
                 }
             }
-            Marker m = Marker.createMarker(wpt, indata.storageFile, this, time, time - firstTime);
+            Double offset = null;
+            // If we have an explicit offset, take it.
+            // Otherwise, for a group of markers with the same Link-URI (e.g. an
+            // audio file) calculate the offset relative to the first marker of
+            // that group. This way the user can jump to the corresponding
+            // playback positions in a long audio track.
+            Extensions exts = (Extensions) wpt.get(GpxConstants.META_EXTENSIONS);
+            if (exts != null && exts.containsKey("offset")) {
+                try {
+                    offset = Double.parseDouble(exts.get("offset"));
+                } catch (NumberFormatException nfe) {}
+            }
+            if (offset == null) {
+                offset = time - firstTime;
+            }
+            Marker m = Marker.createMarker(wpt, indata.storageFile, this, time, offset);
             if (m != null) {
                 data.add(m);
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerProducers.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerProducers.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerProducers.java	(revision 5684)
@@ -24,4 +24,4 @@
      * @return A Marker object, or <code>null</code>.
      */
-    public Marker createMarker(WayPoint wp, File relativePath, MarkerLayer parentLayer, double time, double offset);
+    Marker createMarker(WayPoint wp, File relativePath, MarkerLayer parentLayer, double time, double offset);
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java	(revision 5684)
@@ -6,4 +6,5 @@
 import java.awt.event.ActionEvent;
 import java.net.URL;
+import java.util.Collections;
 
 import javax.swing.JOptionPane;
@@ -11,4 +12,7 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
+import org.openstreetmap.josm.data.gpx.GpxLink;
+import org.openstreetmap.josm.data.gpx.WayPoint;
 import org.openstreetmap.josm.tools.OpenBrowser;
 
@@ -38,3 +42,12 @@
         }
     }
+
+    @Override
+    public WayPoint convertToWayPoint() {
+        WayPoint wpt = super.convertToWayPoint();
+        GpxLink link = new GpxLink(webUrl.toString());
+        link.type = "web";
+        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
+        return wpt;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 5684)
@@ -340,4 +340,7 @@
                     currentState = states.pop();
                     convertUrlToLink(currentWayPoint.attr);
+                    if (currentExtensions != null && !currentExtensions.isEmpty()) {
+                        currentWayPoint.attr.put(META_EXTENSIONS, currentExtensions);
+                    }
                     data.waypoints.add(currentWayPoint);
                 }
Index: trunk/src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 5684)
@@ -11,7 +11,9 @@
 import java.util.Collection;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.Extensions;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
@@ -20,4 +22,5 @@
 import org.openstreetmap.josm.data.gpx.GpxTrack;
 import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
+import org.openstreetmap.josm.data.gpx.IWithAttributes;
 import org.openstreetmap.josm.data.gpx.WayPoint;
 
@@ -42,4 +45,5 @@
     private GpxData data;
     private String indent = "";
+    public String creator = "JOSM GPX export";
 
     private final static int WAY_POINT = 0;
@@ -49,7 +53,24 @@
     public void write(GpxData data) {
         this.data = data;
+        // We write JOSM specific meta information into gpx 'extensions' elements.
+        // In particular it is noted whether the gpx data is from the OSM server
+        // (so the rendering of clouds of anonymous TrackPoints can be improved)
+        // and some extra synchronization info for export of AudioMarkers.
+        // It is checked in advance, if any extensions are used, so we know whether
+        // a namespace declaration is necessary.
+        boolean hasExtensions = data.fromServer;
+        if (!hasExtensions) {
+            for (WayPoint wpt : data.waypoints) {
+                Extensions extensions = (Extensions) wpt.get(META_EXTENSIONS);
+                if (extensions != null && !extensions.isEmpty()) {
+                    hasExtensions = true;
+                    break;
+                }
+            }
+        }
+        
         out.println("<?xml version='1.0' encoding='UTF-8'?>");
         out.println("<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
-                (data.fromServer ? String.format("    xmlns:josm=\"%s\"\n", JOSM_EXTENSIONS_NAMESPACE_URI) : "") +
+                (hasExtensions ? String.format("    xmlns:josm=\"%s\"\n", JOSM_EXTENSIONS_NAMESPACE_URI) : "") +
                 "    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" +
                 "    xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">");
@@ -63,15 +84,23 @@
     }
 
-    @SuppressWarnings("unchecked")
-    private void writeAttr(Map<String, Object> attr) {
+    private void writeAttr(IWithAttributes obj) {
         for (String key : WPT_KEYS) {
-            Object value = attr.get(key);
-            if (value != null) {
-                if (key.equals(META_LINKS)) {
-                    for (GpxLink link : (Collection<GpxLink>) value) {
+            if (key.equals(META_LINKS)) {
+                @SuppressWarnings("unchecked")
+                Collection<GpxLink> lValue = obj.getCollection(key);
+                if (lValue != null) {
+                    for (GpxLink link : lValue) {
                         gpxLink(link);
                     }
-                } else {
-                    simpleTag(key, value.toString());
+                }
+            } else if (key.equals(META_EXTENSIONS)) {
+                Extensions extensions = (Extensions) obj.get(key);
+                if (extensions != null) {
+                    gpxExtensions(extensions);
+                }
+            } else {
+                String value = obj.getString(key);
+                if (value != null) {
+                    simpleTag(key, value);
                 }
             }
@@ -157,5 +186,5 @@
         for (GpxRoute rte : data.routes) {
             openln("rte");
-            writeAttr(rte.attr);
+            writeAttr(rte);
             for (WayPoint pnt : rte.routePoints) {
                 wayPoint(pnt, ROUTE_POINT);
@@ -168,5 +197,5 @@
         for (GpxTrack trk : data.tracks) {
             openln("trk");
-            writeAttr(trk.getAttributes());
+            writeAttr(trk);
             for (GpxTrackSegment seg : trk.getSegments()) {
                 openln("trkseg");
@@ -259,8 +288,18 @@
             } else {
                 openAtt(type, coordAttr);
-                writeAttr(pnt.attr);
+                writeAttr(pnt);
                 closeln(type);
             }
         }
     }
+
+    private void gpxExtensions(Extensions extensions) {
+        if (extensions != null && !extensions.isEmpty()) {
+            openln("extensions");
+            for (Entry<String, String> e : extensions.entrySet()) {
+                simpleTag("josm:" + e.getKey(), e.getValue());
+            }
+            closeln("extensions");
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java	(revision 5684)
@@ -8,13 +8,8 @@
 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;
@@ -95,5 +90,3 @@
     }
 
-
-
 }
Index: trunk/src/org/openstreetmap/josm/io/session/GpxTracksSessionImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/GpxTracksSessionImporter.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/session/GpxTracksSessionImporter.java	(revision 5684)
@@ -13,9 +13,10 @@
 import javax.xml.xpath.XPathFactory;
 
+import org.w3c.dom.Element;
+
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.GpxImporter;
 import org.openstreetmap.josm.io.IllegalDataException;
-import org.w3c.dom.Element;
 
 public class GpxTracksSessionImporter implements SessionLayerImporter {
@@ -36,7 +37,6 @@
             }
 
-            GpxImporter importer = new GpxImporter();
             InputStream in = support.getInputStream(fileStr);
-            GpxImporter.GpxImporterData importData = importer.loadLayers(in, support.getFile(fileStr), support.getLayerName(), null, progressMonitor);
+            GpxImporter.GpxImporterData importData = GpxImporter.loadLayers(in, support.getFile(fileStr), support.getLayerName(), null, progressMonitor);
 
             support.addPostLayersTask(importData.getPostLayerTask());
Index: trunk/src/org/openstreetmap/josm/io/session/ImagerySessionExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/ImagerySessionExporter.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/session/ImagerySessionExporter.java	(revision 5684)
@@ -30,5 +30,6 @@
 
     private ImageryLayer layer;
-
+    private JCheckBox export;
+    
     public ImagerySessionExporter(ImageryLayer layer) {
         this.layer = layer;
@@ -42,6 +43,4 @@
         this((ImageryLayer) layer);
     }
-
-    private JCheckBox export;
 
     @Override
Index: trunk/src/org/openstreetmap/josm/io/session/ImagerySessionImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/ImagerySessionImporter.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/session/ImagerySessionImporter.java	(revision 5684)
@@ -8,4 +8,8 @@
 import java.util.Map;
 
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
 import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
@@ -16,7 +20,4 @@
 import org.openstreetmap.josm.io.IllegalDataException;
 import org.openstreetmap.josm.io.session.SessionReader.ImportSupport;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 /**
Index: trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java	(revision 5684)
+++ trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java	(revision 5684)
@@ -0,0 +1,115 @@
+// 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.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+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.w3c.dom.Element;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.gpx.GpxData;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.markerlayer.Marker;
+import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+import org.openstreetmap.josm.io.GpxWriter;
+import org.openstreetmap.josm.io.session.SessionWriter.ExportSupport;
+import org.openstreetmap.josm.tools.GBC;
+
+public class MarkerSessionExporter implements SessionLayerExporter {
+
+    private MarkerLayer layer;
+    private JCheckBox export;
+
+    public MarkerSessionExporter(MarkerLayer layer) {
+        this.layer = layer;
+    }
+
+    @Override
+    public Collection<Layer> getDependencies() {
+        Layer gpxLayer = layer.fromLayer;
+        if (gpxLayer != null && Main.map.mapView.hasLayer(gpxLayer))
+            return Collections.singleton(gpxLayer);
+        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 true;
+    }
+
+    @Override
+    public Element export(ExportSupport support) throws IOException {
+        Element layerEl = support.createElement("layer");
+        layerEl.setAttribute("type", "markers");
+        layerEl.setAttribute("version", "0.1");
+
+        Element file = support.createElement("file");
+        layerEl.appendChild(file);
+
+        String zipPath = "layers/" + String.format("%02d", support.getLayerIndex()) + "/data.gpx";
+        file.appendChild(support.createTextNode(zipPath));
+        addDataFile(support.getOutputStreamZip(zipPath));
+
+        return layerEl;
+    }
+
+    protected void addDataFile(OutputStream out) throws IOException {
+        Writer writer = null;
+        try {
+            writer = new OutputStreamWriter(out, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+        MarkerWriter w = new MarkerWriter(new PrintWriter(writer));
+        w.write(layer);
+        w.flush();
+    }
+
+    public static class MarkerWriter extends GpxWriter {
+
+        public MarkerWriter(PrintWriter out) {
+            super(out);
+            creator = "JOSM Marker export";
+        }
+
+        public void write(MarkerLayer layer) {
+            GpxData data = new GpxData();
+            data.attr.put(GpxData.META_DESC, "exported JOSM marker layer");
+            for (Marker m : layer.data) {
+                data.waypoints.add(m.convertToWayPoint());
+            }
+            super.write(data);
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/io/session/MarkerSessionImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/MarkerSessionImporter.java	(revision 5684)
+++ trunk/src/org/openstreetmap/josm/io/session/MarkerSessionImporter.java	(revision 5684)
@@ -0,0 +1,66 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.session;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Element;
+
+import org.openstreetmap.josm.gui.layer.GpxLayer;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.GpxImporter;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.io.session.SessionReader.ImportSupport;
+
+public class MarkerSessionImporter implements SessionLayerImporter {
+
+    @Override
+    public Layer load(Element elem, 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 imagery layer is not supported. Expected: 0.1", version));
+        }
+        try {
+            XPathFactory xPathFactory = XPathFactory.newInstance();
+            XPath xpath = xPathFactory.newXPath();
+            XPathExpression fileExp = xpath.compile("file/text()");
+            String fileStr = (String) fileExp.evaluate(elem, XPathConstants.STRING);
+            if (fileStr == null || fileStr.equals("")) {
+                throw new IllegalDataException(tr("File name expected for layer no. {0}", support.getLayerIndex()));
+            }
+
+            InputStream in = support.getInputStream(fileStr);
+            GpxImporter.GpxImporterData importData = GpxImporter.loadLayers(in, support.getFile(fileStr), support.getLayerName(), null, progressMonitor);
+
+            support.addPostLayersTask(importData.getPostLayerTask());
+
+            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;
+                }
+            }
+
+            MarkerLayer markerLayer = importData.getMarkerLayer();
+            markerLayer.fromLayer = gpxLayer;
+            
+            return markerLayer;
+
+        } catch (XPathExpressionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/io/session/OsmDataSessionExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/OsmDataSessionExporter.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/session/OsmDataSessionExporter.java	(revision 5684)
@@ -35,4 +35,6 @@
 import javax.swing.SwingConstants;
 
+import org.w3c.dom.Element;
+
 import org.openstreetmap.josm.actions.SaveAction;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -44,5 +46,4 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.w3c.dom.Element;
 
 public class OsmDataSessionExporter implements SessionLayerExporter {
Index: trunk/src/org/openstreetmap/josm/io/session/SessionReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 5684)
@@ -63,4 +63,5 @@
         registerSessionLayerImporter("tracks", GpxTracksSessionImporter.class);
         registerSessionLayerImporter("geoimage", GeoImageSessionImporter.class);
+        registerSessionLayerImporter("markers", MarkerSessionImporter.class);
     }
 
@@ -305,5 +306,5 @@
                 if (scaleEl != null && scaleEl.hasAttribute("meter-per-pixel")) {
                     try {
-                        Double meterPerPixel = Double.parseDouble(scaleEl.getAttribute("meter-per-pixel"));
+                        double meterPerPixel = Double.parseDouble(scaleEl.getAttribute("meter-per-pixel"));
                         Projection proj = Main.getProjection();
                         // Get a "typical" distance in east/north units that
Index: trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 5681)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 5684)
@@ -28,4 +28,8 @@
 import javax.xml.transform.stream.StreamResult;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -38,9 +42,7 @@
 import org.openstreetmap.josm.gui.layer.WMSLayer;
 import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
+import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Text;
 
 public class SessionWriter {
@@ -54,4 +56,5 @@
         registerSessionLayerExporter(GpxLayer.class , GpxTracksSessionExporter.class);
         registerSessionLayerExporter(GeoImageLayer.class , GeoImageSessionExporter.class);
+        registerSessionLayerExporter(MarkerLayer.class, MarkerSessionExporter.class);
     }
 
