### Eclipse Workspace Patch 1.0
#P josm
Index: src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 18580)
+++ src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(working copy)
@@ -168,6 +168,10 @@
                 data.addAll(markers);
             }
         }
+
+        if (fromLayer != null && !data.isEmpty()) {
+            fromLayer.setLinkedMarkerLayer(this);
+        }
     }
 
     @Override
Index: src/org/openstreetmap/josm/actions/SaveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveAction.java	(revision 18580)
+++ src/org/openstreetmap/josm/actions/SaveAction.java	(working copy)
@@ -4,28 +4,16 @@
 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.GridBagLayout;
 import java.awt.event.KeyEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
 
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.SwingConstants;
-
-import org.openstreetmap.josm.data.gpx.GpxConstants;
-import org.openstreetmap.josm.gui.ExtendedDialog;
-import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
-import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
 import org.openstreetmap.josm.gui.layer.SaveToFile;
 import org.openstreetmap.josm.gui.util.GuiHelper;
-import org.openstreetmap.josm.spi.preferences.Config;
-import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
@@ -100,41 +88,9 @@
     @Override
     public File getFile(Layer layer) {
         File f = layer.getAssociatedFile();
-        if (f != null && !f.exists()) {
-            f = null;
+        if (f == null || !f.exists()) {
+            f = layer.createAndOpenSaveFileChooser();
         }
-
-        // Ask for overwrite in case of GpxLayer
-        if (f != null
-                && layer instanceof GpxLayer
-                && (((GpxLayer) layer).data == null
-                || !GpxConstants.JOSM_CREATOR_NAME.equals(((GpxLayer) layer).data.creator))
-                && !Config.getPref().getBoolean("gpx.export.overwrite", false)) {
-
-            JPanel p = new JPanel(new GridBagLayout());
-            JLabel label = new JLabel("<html>"
-                    + tr("The file \"{0}\" will be modified.<br>Would you like to overwrite the existing file?", f.getName())
-                    + "</html>");
-            label.setHorizontalAlignment(SwingConstants.CENTER);
-            JCheckBox remember = new JCheckBox(tr("Always overwrite GPX files without asking"));
-            remember.setHorizontalAlignment(SwingConstants.CENTER);
-            p.add(label, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 10));
-            p.add(remember, GBC.eop().fill(GBC.HORIZONTAL));
-            ExtendedDialog dialog = new ExtendedDialog(
-                    MainApplication.getMainFrame(),
-                    tr("Overwrite"),
-                    tr("Overwrite"), tr("Save As..."), tr("Cancel"))
-                .setButtonIcons("save", "save_as", "cancel")
-                .setContent(p);
-            int val = dialog.showDialog().getValue();
-            if (val == 1) {
-                Config.getPref().putBoolean("gpx.export.overwrite", remember.isSelected());
-            } else if (val == 2) {
-                f = null;
-            } else {
-                return null;
-            }
-        }
-        return f == null ? layer.createAndOpenSaveFileChooser() : f;
+        return f;
     }
 }
Index: src/org/openstreetmap/josm/actions/SaveActionBase.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 18580)
+++ src/org/openstreetmap/josm/actions/SaveActionBase.java	(working copy)
@@ -135,6 +135,7 @@
             return false;
 
         Notification savingNotification = showSavingNotification(file.getName());
+        layer.setAssociatedFile(file);
         try {
             boolean exported = false;
             boolean canceled = false;
@@ -145,6 +146,7 @@
                     } else {
                         exporter.exportData(file, layer);
                     }
+                    file = layer.getAssociatedFile();
                     exported = true;
                     canceled = exporter.isCanceled();
                     break;
@@ -161,7 +163,6 @@
             if (!layer.isRenamed()) {
                 layer.setName(file.getName());
             }
-            layer.setAssociatedFile(file);
             if (layer instanceof AbstractModifiableLayer) {
                 ((AbstractModifiableLayer) layer).onPostSaveToFile();
             }
Index: src/org/openstreetmap/josm/io/nmea/NmeaReader.java
===================================================================
--- src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 18580)
+++ src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(working copy)
@@ -232,7 +232,7 @@
     @Override
     public boolean parse(boolean tryToFinish) throws SAXException, IOException {
         // create the data tree
-        data = new GpxData();
+        data = new GpxData(true);
         Collection<Collection<WayPoint>> currentTrack = new ArrayList<>();
 
         try (BufferedReader rd = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) {
@@ -268,6 +268,8 @@
         } catch (IllegalDataException e) {
             Logging.warn(e);
             return false;
+        } finally {
+            data.endUpdate();
         }
         return true;
     }
Index: src/org/openstreetmap/josm/io/ozi/OziWptReader.java
===================================================================
--- src/org/openstreetmap/josm/io/ozi/OziWptReader.java	(revision 18580)
+++ src/org/openstreetmap/josm/io/ozi/OziWptReader.java	(working copy)
@@ -51,7 +51,7 @@
 
     @Override
     public boolean parse(boolean tryToFinish) throws SAXException, IOException {
-        data = new GpxData();
+        data = new GpxData(true);
         Collection<Collection<WayPoint>> currentTrack = new ArrayList<>();
         Collection<WayPoint> waypoints = new ArrayList<>();
         try (BufferedReader rd = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) {
@@ -97,6 +97,7 @@
         }
         currentTrack.add(waypoints);
         data.tracks.add(new GpxTrack(currentTrack, Collections.<String, Object>emptyMap()));
+        data.endUpdate();
         return true;
     }
 
Index: src/org/openstreetmap/josm/io/rtklib/RtkLibPosReader.java
===================================================================
--- src/org/openstreetmap/josm/io/rtklib/RtkLibPosReader.java	(revision 18580)
+++ src/org/openstreetmap/josm/io/rtklib/RtkLibPosReader.java	(working copy)
@@ -60,7 +60,7 @@
 
     @Override
     public boolean parse(boolean tryToFinish) throws SAXException, IOException {
-        data = new GpxData();
+        data = new GpxData(true);
         Collection<Collection<WayPoint>> currentTrack = new ArrayList<>();
         Collection<WayPoint> waypoints = new ArrayList<>();
         try (BufferedReader rd = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) {
@@ -102,6 +102,7 @@
         }
         currentTrack.add(waypoints);
         data.tracks.add(new GpxTrack(currentTrack, Collections.<String, Object>emptyMap()));
+        data.endUpdate();
         return true;
     }
 
Index: src/org/openstreetmap/josm/actions/SaveAsAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveAsAction.java	(revision 18580)
+++ src/org/openstreetmap/josm/actions/SaveAsAction.java	(working copy)
@@ -29,6 +29,20 @@
     }
 
     /**
+     * A file indicating that a potential overwrite has been confirmed by the user
+     * @since xxx
+     */
+    public static class OverwritableFile extends File {
+        /**
+         * Construct an @link {@link OverwritableFile}
+         * @param pathname A pathname String
+         */
+        public OverwritableFile(String pathname) {
+            super(pathname);
+        }
+    }
+
+    /**
      * Returns the unique instance.
      * @return the unique instance
      */
@@ -37,6 +51,6 @@
     }
 
     @Override protected File getFile(Layer layer) {
-        return layer.createAndOpenSaveFileChooser();
+        return new OverwritableFile(layer.createAndOpenSaveFileChooser().getPath());
     }
 }
Index: src/org/openstreetmap/josm/gui/io/importexport/GpxExporter.java
===================================================================
--- src/org/openstreetmap/josm/gui/io/importexport/GpxExporter.java	(revision 18580)
+++ src/org/openstreetmap/josm/gui/io/importexport/GpxExporter.java	(working copy)
@@ -25,7 +25,9 @@
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.ListSelectionModel;
+import javax.swing.SwingConstants;
 
+import org.openstreetmap.josm.actions.SaveAsAction;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
@@ -42,6 +44,7 @@
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
  * Exports data to a .gpx file. Data may be native GPX or OSM data which will be converted.
@@ -78,7 +81,7 @@
 
     @Override
     public boolean acceptFile(File pathname, Layer layer) {
-        return isSupportedLayer(layer) ? super.acceptFile(pathname, layer) : false;
+        return isSupportedLayer(layer);
     }
 
     @Override
@@ -98,24 +101,68 @@
                     .getClass().getName()));
         CheckParameterUtil.ensureParameterNotNull(file, "file");
 
-        String fn = file.getPath();
-        if (fn.indexOf('.') == -1) {
-            fn += ".gpx";
-            file = new File(fn);
+        if (!Utils.hasExtension(file, "gpx")) {
+            String pth = file.getPath() + ".gpx";
+            file = new File(pth);
         }
 
-        GpxData gpxData;
-        if (quiet) {
-            gpxData = getGpxData(layer, file);
-            try (OutputStream fo = Compression.getCompressedFileOutputStream(file)) {
-                GpxWriter w = new GpxWriter(fo);
-                w.write(gpxData);
-                w.close();
-                fo.flush();
+        // Ask if GPX file should be overwritten
+        if (!(file instanceof SaveAsAction.OverwritableFile)
+                && file.exists()
+                && (((GpxLayer) layer).data == null || !GpxConstants.JOSM_CREATOR_NAME.equals(((GpxLayer) layer).data.creator))
+                && !Config.getPref().getBoolean("gpx.export.overwrite", false)) {
+
+            JPanel p = new JPanel(new GridBagLayout());
+            JLabel label = new JLabel("<html>"
+                    + tr("The file \"{0}\" will be modified.<br>Would you like to overwrite the existing file?", file.getName())
+                    + "</html>");
+            label.setHorizontalAlignment(SwingConstants.CENTER);
+            JCheckBox remember = new JCheckBox(tr("Always overwrite GPX files without asking"));
+            remember.setHorizontalAlignment(SwingConstants.CENTER);
+            p.add(label, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 10));
+            p.add(remember, GBC.eop().fill(GBC.HORIZONTAL));
+            ExtendedDialog dialog = new ExtendedDialog(
+                    MainApplication.getMainFrame(),
+                    tr("Overwrite"),
+                    tr("Overwrite"), tr("Save As..."), tr("Cancel"))
+                .setButtonIcons("save", "save_as", "cancel")
+                .setContent(p);
+            int val = dialog.showDialog().getValue();
+            if (val == 1) {
+                Config.getPref().putBoolean("gpx.export.overwrite", remember.isSelected());
+            } else if (val == 2) {
+                file = layer.createAndOpenSaveFileChooser();
+            } else {
+                file = null;
             }
+        }
+
+        if (file == null) {
+            setCanceled(true);
             return;
         }
 
+        GpxWriteOptions opts;
+        if (quiet) {
+            opts = new GpxWriteOptions(getGpxData(layer, file), ColorFormat.GPXD, true);
+        } else {
+            opts = askGpxAttributes(layer, file);
+        }
+
+        if (opts == null) return;
+        layer.setAssociatedFile(file);
+
+        try (OutputStream fo = Compression.getCompressedFileOutputStream(file)) {
+            GpxWriter w = new GpxWriter(fo);
+            w.write(opts.gpxData, opts.cFormat, opts.saveLayerPrefs);
+            w.close();
+            fo.flush();
+        }
+    }
+
+    private GpxWriteOptions askGpxAttributes(Layer layer, File file) {
+        GpxData gpxData;
+
         // open the dialog asking for options
         JPanel p = new JPanel(new GridBagLayout());
 
@@ -217,7 +264,7 @@
 
         if (ed.showDialog().getValue() != 1) {
             setCanceled(true);
-            return;
+            return null;
         }
         setCanceled(false);
 
@@ -267,12 +314,7 @@
             gpxData.put(META_KEYWORDS, keywords.getText());
         }
 
-        try (OutputStream fo = Compression.getCompressedFileOutputStream(file)) {
-            GpxWriter w = new GpxWriter(fo);
-            w.write(gpxData, cFormat, layerPrefs.isSelected());
-            w.close();
-            fo.flush();
-        }
+        return new GpxWriteOptions(gpxData, cFormat, layerPrefs.isSelected());
     }
 
     /**
@@ -423,4 +465,16 @@
         authorActionListener.actionPerformed(null);
         authorNameListener.keyReleased(null);
     }
+
+    private static class GpxWriteOptions {
+        GpxData gpxData;
+        ColorFormat cFormat;
+        boolean saveLayerPrefs;
+
+        GpxWriteOptions(GpxData gpxData, ColorFormat cFormat, boolean saveLayerPrefs) {
+            this.gpxData = gpxData;
+            this.cFormat = cFormat;
+            this.saveLayerPrefs = saveLayerPrefs;
+        }
+    }
 }
Index: src/org/openstreetmap/josm/gui/io/importexport/GpxImporter.java
===================================================================
--- src/org/openstreetmap/josm/gui/io/importexport/GpxImporter.java	(revision 18580)
+++ src/org/openstreetmap/josm/gui/io/importexport/GpxImporter.java	(working copy)
@@ -175,8 +175,6 @@
             markerLayer = new MarkerLayer(data, tr("Markers from {0}", gpxLayerName), data.storageFile, gpxLayer);
             if (markerLayer.data.isEmpty()) {
                 markerLayer = null;
-            } else {
-                gpxLayer.setLinkedMarkerLayer(markerLayer);
             }
         }
         if (Config.getPref().getBoolean("gpx.makeautoroutes", true) && !data.getRoutes().isEmpty()) {
