Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java	(revision 7518)
@@ -3,4 +3,5 @@
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 
@@ -11,4 +12,18 @@
  */
 public interface GpxConstants {
+
+    /** GPS name of the element. This field will be transferred to and from the GPS.
+     *  GPX does not place restrictions on the length of this field or the characters contained in it.
+     *  It is up to the receiving application to validate the field before sending it to the GPS. */
+    public static final String GPX_NAME = "name";
+
+    /** GPS element comment. Sent to GPS as comment. */
+    public static final String GPX_CMT = "cmt";
+
+    /** Text description of the element. Holds additional information about the element intended for the user, not the GPS. */
+    public static final String GPX_DESC = "desc";
+
+    /** Source of data. Included to give user some idea of reliability and accuracy of data. */
+    public static final String GPX_SRC = "src";
 
     public static final String META_PREFIX = "meta.";
@@ -28,7 +43,62 @@
     public static final String JOSM_EXTENSIONS_NAMESPACE_URI = Main.getXMLBase() + "/gpx-extensions-1.0";
 
-    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", META_EXTENSIONS);
+    /** Elevation (in meters) of the point. */
+    public static final String PT_ELE = "ele";
 
+    /** Creation/modification timestamp for the point.
+     *  Date and time in are in Univeral Coordinated Time (UTC), not local time!
+     *  Conforms to ISO 8601 specification for date/time representation.
+     *  Fractional seconds are allowed for millisecond timing in tracklogs. */
+    public static final String PT_TIME = "time";
+
+    /** Magnetic variation (in degrees) at the point. 0.0 <= value < 360.0 */
+    public static final String PT_MAGVAR = "magvar";
+
+    /** Height, in meters, of geoid (mean sea level) above WGS-84 earth ellipsoid. (NMEA GGA message) */
+    public static final String PT_GEOIDHEIGHT = "geoidheight";
+
+    /** Text of GPS symbol name. For interchange with other programs, use the exact spelling of the symbol on the GPS, if known. */
+    public static final String PT_SYM = "sym";
+
+    /** Type (textual classification) of element. */
+    public static final String PT_TYPE = "type";
+
+    /** Type of GPS fix. none means GPS had no fix. Value comes from list: {'none'|'2d'|'3d'|'dgps'|'pps'} */
+    public static final String PT_FIX = "fix";
+
+    /** Number of satellites used to calculate the GPS fix. (not number of satellites in view). */
+    public static final String PT_SAT = "sat";
+
+    /** Horizontal dilution of precision. */
+    public static final String PT_HDOP = "hdop";
+
+    /** Vertical dilution of precision. */
+    public static final String PT_VDOP = "vdop";
+
+    /** Position dilution of precision. */
+    public static final String PT_PDOP = "pdop";
+
+    /** Number of seconds since last DGPS update. */
+    public static final String PT_AGEOFDGPSDATA = "ageofdgpsdata";
+
+    /** Represents a differential GPS station. 0 <= value <= 1023 */
+    public static final String PT_DGPSID = "dgpsid";
+
+    /**
+     * Ordered list of all possible waypoint keys.
+     */
+    public static List<String> WPT_KEYS = Arrays.asList(PT_ELE, PT_TIME, PT_MAGVAR, PT_GEOIDHEIGHT,
+            GPX_NAME, GPX_CMT, GPX_DESC, GPX_SRC, META_LINKS, PT_SYM, PT_TYPE,
+            PT_FIX, PT_SAT, PT_HDOP, PT_VDOP, PT_PDOP, PT_AGEOFDGPSDATA, PT_DGPSID, META_EXTENSIONS);
+
+    /**
+     * Ordered list of all possible route and track keys.
+     */
+    public static List<String> RTE_TRK_KEYS = Arrays.asList(
+            GPX_NAME, GPX_CMT, GPX_DESC, GPX_SRC, META_LINKS, "number", PT_TYPE, META_EXTENSIONS);
+
+    /**
+     * Possible fix values.
+     */
+    public static Collection<String> FIX_VALUES = Arrays.asList("none","2d","3d","dgps","pps");
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 7518)
@@ -41,11 +41,10 @@
             String k = ent.getKey();
             if (k.equals(META_LINKS) && attr.containsKey(META_LINKS)) {
-                @SuppressWarnings("unchecked")
-                Collection<GpxLink> my = (Collection<GpxLink>) attr.get(META_LINKS);
+                Collection<GpxLink> my = super.<GpxLink>getCollection(META_LINKS);
                 @SuppressWarnings("unchecked")
                 Collection<GpxLink> their = (Collection<GpxLink>) ent.getValue();
                 my.addAll(their);
             } else {
-                attr.put(k, ent.getValue());
+                put(k, ent.getValue());
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxLink.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxLink.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxLink.java	(revision 7518)
@@ -2,9 +2,23 @@
 package org.openstreetmap.josm.data.gpx;
 
+/**
+ * A link to an external resource (Web page, digital photo, video clip, etc) with additional information.
+ * @since 444
+ */
 public class GpxLink {
+
+    /** External resource URI */
     public String uri;
+
+    /** Text to display on the hyperlink */
     public String text;
+
+    /** Link type */
     public String type;
 
+    /**
+     * Constructs a new {@code GpxLink}.
+     * @param uri External resource URI
+     */
     public GpxLink(String uri) {
         this.uri = uri;
Index: trunk/src/org/openstreetmap/josm/data/gpx/IWithAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/IWithAttributes.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/data/gpx/IWithAttributes.java	(revision 7518)
@@ -37,5 +37,5 @@
      * @since 5502
      */
-    Collection<?> getCollection(String key);
+    <T> Collection<T> getCollection(String key);
 
     /**
Index: trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 7518)
@@ -95,5 +95,5 @@
     @Override
     public String toString() {
-        return "WayPoint (" + (attr.containsKey("name") ? attr.get("name") + ", " :"") + getCoor().toString() + ", " + attr + ")";
+        return "WayPoint (" + (attr.containsKey(GPX_NAME) ? get(GPX_NAME) + ", " :"") + getCoor().toString() + ", " + attr + ")";
     }
 
@@ -102,7 +102,7 @@
      */
     public void setTime() {
-        if(attr.containsKey("time")) {
+        if (attr.containsKey(PT_TIME)) {
             try {
-                time = dateParser.get().parse(attr.get("time").toString()).getTime() / 1000.; /* ms => seconds */
+                time = dateParser.get().parse(get(PT_TIME).toString()).getTime() / 1000.; /* ms => seconds */
             } catch(Exception e) {
                 time = 0;
@@ -123,5 +123,5 @@
     public Object getTemplateValue(String name, boolean special) {
         if (!special)
-            return attr.get(name);
+            return get(name);
         else
             return null;
Index: trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java	(revision 7518)
@@ -56,8 +56,9 @@
      * @since 5502
      */
+    @SuppressWarnings("unchecked")
     @Override
-    public Collection<?> getCollection(String key) {
+    public <T> Collection<T> getCollection(String key) {
         Object value = attr.get(key);
-        return (value instanceof Collection) ? (Collection<?>)value : null;
+        return (value instanceof Collection) ? (Collection<T>)value : null;
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 7518)
@@ -64,5 +64,5 @@
 
     public GpxLayer(GpxData d) {
-        super((String) d.attr.get("name"));
+        super(d.getString(GpxConstants.META_NAME));
         data = d;
         drawHelper = new GpxDrawHelper(data);
@@ -124,9 +124,9 @@
 
         if (data.attr.containsKey("name")) {
-            info.append(tr("Name: {0}", data.attr.get(GpxConstants.META_NAME))).append("<br>");
+            info.append(tr("Name: {0}", data.get(GpxConstants.META_NAME))).append("<br>");
         }
 
         if (data.attr.containsKey("desc")) {
-            info.append(tr("Description: {0}", data.attr.get(GpxConstants.META_DESC))).append("<br>");
+            info.append(tr("Description: {0}", data.get(GpxConstants.META_DESC))).append("<br>");
         }
 
@@ -141,10 +141,10 @@
             for (GpxTrack trk : data.tracks) {
                 info.append("<tr><td>");
-                if (trk.getAttributes().containsKey("name")) {
-                    info.append(trk.getAttributes().get("name"));
+                if (trk.getAttributes().containsKey(GpxConstants.GPX_NAME)) {
+                    info.append(trk.get(GpxConstants.GPX_NAME));
                 }
                 info.append("</td><td>");
-                if (trk.getAttributes().containsKey("desc")) {
-                    info.append(" ").append(trk.getAttributes().get("desc"));
+                if (trk.getAttributes().containsKey(GpxConstants.GPX_DESC)) {
+                    info.append(" ").append(trk.get(GpxConstants.GPX_DESC));
                 }
                 info.append("</td><td>");
@@ -154,5 +154,5 @@
                 info.append("</td><td>");
                 if (trk.getAttributes().containsKey("url")) {
-                    info.append(trk.getAttributes().get("url"));
+                    info.append(trk.get("url"));
                 }
                 info.append("</td></tr>");
@@ -215,10 +215,10 @@
         StringBuilder info = new StringBuilder().append("<html>");
 
-        if (data.attr.containsKey("name")) {
-            info.append(tr("Name: {0}", data.attr.get(GpxConstants.META_NAME))).append("<br>");
-        }
-
-        if (data.attr.containsKey("desc")) {
-            info.append(tr("Description: {0}", data.attr.get(GpxConstants.META_DESC))).append("<br>");
+        if (data.attr.containsKey(GpxConstants.META_NAME)) {
+            info.append(tr("Name: {0}", data.get(GpxConstants.META_NAME))).append("<br>");
+        }
+
+        if (data.attr.containsKey(GpxConstants.META_DESC)) {
+            info.append(tr("Description: {0}", data.get(GpxConstants.META_DESC))).append("<br>");
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 7518)
@@ -51,5 +51,7 @@
 import org.openstreetmap.josm.data.conflict.ConflictCollection;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
+import org.openstreetmap.josm.data.gpx.GpxLink;
 import org.openstreetmap.josm.data.gpx.ImmutableGpxTrack;
 import org.openstreetmap.josm.data.gpx.WayPoint;
@@ -581,5 +583,5 @@
                 WayPoint wpt = new WayPoint(n.getCoor());
                 if (!n.isTimestampEmpty()) {
-                    wpt.attr.put("time", DateUtils.fromDate(n.getTimestamp()));
+                    wpt.put("time", DateUtils.fromDate(n.getTimestamp()));
                     wpt.setTime();
                 }
@@ -600,18 +602,106 @@
             }
             WayPoint wpt = new WayPoint(n.getCoor());
-            String name = n.get("name");
-            if (name != null) {
-                wpt.attr.put("name", name);
-            }
+
+            // Position info
+
+            addDoubleIfPresent(wpt, n, GpxConstants.PT_ELE);
+
             if (!n.isTimestampEmpty()) {
-                wpt.attr.put("time", DateUtils.fromDate(n.getTimestamp()));
+                wpt.put("time", DateUtils.fromDate(n.getTimestamp()));
                 wpt.setTime();
             }
-            String desc = n.get("description");
-            if (desc != null) {
-                wpt.attr.put("desc", desc);
-            }
+
+            addDoubleIfPresent(wpt, n, GpxConstants.PT_MAGVAR);
+            addDoubleIfPresent(wpt, n, GpxConstants.PT_GEOIDHEIGHT);
+
+            // Description info
+
+            addStringIfPresent(wpt, n, GpxConstants.GPX_NAME);
+            addStringIfPresent(wpt, n, GpxConstants.GPX_DESC, "description");
+            addStringIfPresent(wpt, n, GpxConstants.GPX_CMT, "comment");
+            addStringIfPresent(wpt, n, GpxConstants.GPX_SRC, "source", "source:position");
+
+            Collection<GpxLink> links = new ArrayList<>();
+            for (String key : new String[]{"link", "url", "website", "contact:website"}) {
+                String value = n.get(key);
+                if (value != null) {
+                    links.add(new GpxLink(value));
+                }
+            }
+            wpt.put(GpxConstants.META_LINKS, links);
+
+            addStringIfPresent(wpt, n, GpxConstants.PT_SYM, "wpt_symbol");
+            addStringIfPresent(wpt, n, GpxConstants.PT_TYPE);
+
+            // Accuracy info
+            addStringIfPresent(wpt, n, GpxConstants.PT_FIX, "gps:fix");
+            addIntegerIfPresent(wpt, n, GpxConstants.PT_SAT, "gps:sat");
+            addDoubleIfPresent(wpt, n, GpxConstants.PT_HDOP, "gps:hdop");
+            addDoubleIfPresent(wpt, n, GpxConstants.PT_VDOP, "gps:vdop");
+            addDoubleIfPresent(wpt, n, GpxConstants.PT_PDOP, "gps:pdop");
+            addDoubleIfPresent(wpt, n, GpxConstants.PT_AGEOFDGPSDATA, "gps:ageofdgpsdata");
+            addIntegerIfPresent(wpt, n, GpxConstants.PT_DGPSID, "gps:dgpsid");
 
             gpxData.waypoints.add(wpt);
+        }
+    }
+
+    private static void addIntegerIfPresent(WayPoint wpt, OsmPrimitive p, String gpxKey, String ... osmKeys) {
+        ArrayList<String> possibleKeys = new ArrayList<>(Arrays.asList(osmKeys));
+        possibleKeys.add(0, gpxKey);
+        for (String key : possibleKeys) {
+            String value = p.get(key);
+            if (value != null) {
+                try {
+                    int i = Integer.parseInt(value);
+                    // Sanity checks
+                    if ((!GpxConstants.PT_SAT.equals(gpxKey) || i >= 0) &&
+                        (!GpxConstants.PT_DGPSID.equals(gpxKey) || (0 <= i && i <= 1023))) {
+                        wpt.put(gpxKey, value);
+                        break;
+                    }
+                } catch (NumberFormatException e) {
+                    if (Main.isTraceEnabled()) {
+                        Main.trace(e.getMessage());
+                    }
+                }
+            }
+        }
+    }
+
+    private static void addDoubleIfPresent(WayPoint wpt, OsmPrimitive p, String gpxKey, String ... osmKeys) {
+        ArrayList<String> possibleKeys = new ArrayList<>(Arrays.asList(osmKeys));
+        possibleKeys.add(0, gpxKey);
+        for (String key : possibleKeys) {
+            String value = p.get(key);
+            if (value != null) {
+                try {
+                    double d = Double.parseDouble(value);
+                    // Sanity checks
+                    if (!GpxConstants.PT_MAGVAR.equals(gpxKey) || (0.0 <= d && d < 360.0)) {
+                        wpt.put(gpxKey, value);
+                        break;
+                    }
+                } catch (NumberFormatException e) {
+                    if (Main.isTraceEnabled()) {
+                        Main.trace(e.getMessage());
+                    }
+                }
+            }
+        }
+    }
+
+    private static void addStringIfPresent(WayPoint wpt, OsmPrimitive p, String gpxKey, String ... osmKeys) {
+        ArrayList<String> possibleKeys = new ArrayList<>(Arrays.asList(osmKeys));
+        possibleKeys.add(0, gpxKey);
+        for (String key : possibleKeys) {
+            String value = p.get(key);
+            if (value != null) {
+                // Sanity checks
+                if (!GpxConstants.PT_FIX.equals(gpxKey) || GpxConstants.FIX_VALUES.contains(value)) {
+                    wpt.put(gpxKey, value);
+                    break;
+                }
+            }
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 7518)
@@ -63,4 +63,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.DiskAccessAction;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.GpxTrack;
@@ -1012,5 +1013,5 @@
                 for (GpxTrackSegment segment : trk.getSegments()) {
                     for (WayPoint curWp : segment.getWayPoints()) {
-                        String curDateWpStr = (String) curWp.attr.get("time");
+                        String curDateWpStr = curWp.getString(GpxConstants.PT_TIME);
                         if (curDateWpStr == null) {
                             continue;
@@ -1136,5 +1137,5 @@
                 for (WayPoint curWp : segment.getWayPoints()) {
 
-                    String curWpTimeStr = (String) curWp.attr.get("time");
+                    String curWpTimeStr = curWp.getString(GpxConstants.PT_TIME);
                     if (curWpTimeStr != null) {
 
@@ -1163,5 +1164,5 @@
 
     private static Double getElevation(WayPoint wp) {
-        String value = (String) wp.attr.get("ele");
+        String value = wp.getString(GpxConstants.PT_ELE);
         if (value != null) {
             try {
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 7518)
@@ -32,4 +32,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxTrack;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -111,6 +112,6 @@
         for (GpxTrack trk : layer.data.tracks) {
             Map<String, Object> attr = trk.getAttributes();
-            String name = (String) (attr.containsKey("name") ? attr.get("name") : "");
-            String desc = (String) (attr.containsKey("desc") ? attr.get("desc") : "");
+            String name = (String) (attr.containsKey(GpxConstants.GPX_NAME) ? attr.get(GpxConstants.GPX_NAME) : "");
+            String desc = (String) (attr.containsKey(GpxConstants.GPX_DESC) ? attr.get(GpxConstants.GPX_DESC) : "");
             String time = GpxLayer.getTimespanForTrack(trk);
             TrackLength length = new TrackLength(trk.length());
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java	(revision 7518)
@@ -16,4 +16,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxTrack;
 import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
@@ -53,5 +54,5 @@
                 for (WayPoint p : segment.getWayPoints()) {
                     Node n = new Node(p.getCoor());
-                    String timestr = p.getString("time");
+                    String timestr = p.getString(GpxConstants.PT_TIME);
                     if (timestr != null) {
                         n.setTimestamp(DateUtils.fromString(timestr));
@@ -68,4 +69,3 @@
         Main.main.removeLayer(layer);
     }
-
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 7518)
@@ -17,4 +17,5 @@
 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.GpxData;
 import org.openstreetmap.josm.data.gpx.WayPoint;
@@ -253,5 +254,5 @@
                 for (Collection<WayPoint> segment : data.getLinesIterable(null)) {
                     for (WayPoint trkPnt : segment) {
-                        Object val = trkPnt.attr.get("hdop");
+                        Object val = trkPnt.get(GpxConstants.PT_HDOP);
                         if (val != null) {
                             double hdop = ((Float) val).doubleValue();
@@ -304,5 +305,5 @@
 
                 if (colored == ColorMode.HDOP) {
-                    Float hdop = (Float) trkPnt.attr.get("hdop");
+                    Float hdop = (Float) trkPnt.get(GpxConstants.PT_HDOP);
                     color = hdopScale.getColor(hdop);
                 }
@@ -446,7 +447,7 @@
 
 
-                if (hdopCircle && trkPnt.attr.get("hdop") != null) {
+                if (hdopCircle && trkPnt.get(GpxConstants.PT_HDOP) != null) {
                     // hdop value
-                    float hdop = (Float)trkPnt.attr.get("hdop");
+                    float hdop = (Float)trkPnt.get(GpxConstants.PT_HDOP);
                     if (hdop < 0) {
                         hdop = 0;
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/ImportAudioAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/ImportAudioAction.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/ImportAudioAction.java	(revision 7518)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.DiskAccessAction;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.GpxTrack;
@@ -184,6 +185,6 @@
                     WayPoint wc = new WayPoint(w.getCoor());
                     wc.time = wNear.time;
-                    if (w.attr.containsKey("name")) {
-                        wc.attr.put("name", w.getString("name"));
+                    if (w.attr.containsKey(GpxConstants.GPX_NAME)) {
+                        wc.put(GpxConstants.GPX_NAME, w.getString(GpxConstants.GPX_NAME));
                     }
                     waypoints.add(wc);
@@ -200,5 +201,5 @@
                 for (GpxTrackSegment seg : track.getSegments()) {
                     for (WayPoint w : seg.getWayPoints()) {
-                        if (w.attr.containsKey("name") || w.attr.containsKey("desc")) {
+                        if (w.attr.containsKey(GpxConstants.GPX_NAME) || w.attr.containsKey(GpxConstants.GPX_DESC)) {
                             waypoints.add(w);
                         }
@@ -245,5 +246,5 @@
                     name = name.substring(0, dot);
                 }
-                wayPointFromTimeStamp.attr.put("name", name);
+                wayPointFromTimeStamp.put(GpxConstants.GPX_NAME, name);
                 waypoints.add(wayPointFromTimeStamp);
             }
@@ -259,5 +260,5 @@
                     for (WayPoint w : seg.getWayPoints()) {
                         WayPoint wStart = new WayPoint(w.getCoor());
-                        wStart.attr.put("name", "start");
+                        wStart.put(GpxConstants.GPX_NAME, "start");
                         wStart.time = w.time;
                         waypoints.add(wStart);
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/AudioMarker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/AudioMarker.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/AudioMarker.java	(revision 7518)
@@ -87,5 +87,5 @@
         GpxLink link = new GpxLink(audioUrl.toString());
         link.type = "audio";
-        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
+        wpt.put(GpxConstants.META_LINKS, Collections.singleton(link));
         wpt.addExtension("offset", Double.toString(offset));
         wpt.addExtension("sync-offset", Double.toString(syncOffset));
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ImageMarker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ImageMarker.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ImageMarker.java	(revision 7518)
@@ -93,7 +93,6 @@
         GpxLink link = new GpxLink(imageUrl.toString());
         link.type = "image";
-        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
+        wpt.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 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 7518)
@@ -181,5 +181,4 @@
     static {
         Marker.markerProducers.add(new MarkerProducers() {
-            @SuppressWarnings("unchecked")
             @Override
             public Marker createMarker(WayPoint wpt, File relativePath, MarkerLayer parentLayer, double time, double offset) {
@@ -187,5 +186,5 @@
                 // cheapest way to check whether "link" object exists and is a non-empty
                 // collection of GpxLink objects...
-                Collection<GpxLink> links = (Collection<GpxLink>)wpt.attr.get(GpxConstants.META_LINKS);
+                Collection<GpxLink> links = wpt.<GpxLink>getCollection(GpxConstants.META_LINKS);
                 if (links != null) {
                     for (GpxLink oneLink : links ) {
@@ -210,5 +209,5 @@
                     String symbolName = wpt.getString("symbol");
                     if (symbolName == null) {
-                        symbolName = wpt.getString("sym");
+                        symbolName = wpt.getString(GpxConstants.PT_SYM);
                     }
                     return new Marker(wpt.getCoor(), wpt, symbolName, parentLayer, time, offset);
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 7518)
@@ -94,21 +94,17 @@
             if (firstTime < 0 && wpt_has_link) {
                 firstTime = time;
-                for (Object oneLink : wpt.getCollection(GpxConstants.META_LINKS)) {
-                    if (oneLink instanceof GpxLink) {
-                        lastLinkedFile = ((GpxLink)oneLink).uri;
-                        break;
+                for (GpxLink oneLink : wpt.<GpxLink>getCollection(GpxConstants.META_LINKS)) {
+                    lastLinkedFile = oneLink.uri;
+                    break;
+                }
+            }
+            if (wpt_has_link) {
+                for (GpxLink oneLink : wpt.<GpxLink>getCollection(GpxConstants.META_LINKS)) {
+                    String uri = oneLink.uri;
+                    if (!uri.equals(lastLinkedFile)) {
+                        firstTime = time;
                     }
-                }
-            }
-            if (wpt_has_link) {
-                for (Object oneLink : wpt.getCollection(GpxConstants.META_LINKS)) {
-                    if (oneLink instanceof GpxLink) {
-                        String uri = ((GpxLink)oneLink).uri;
-                        if (!uri.equals(lastLinkedFile)) {
-                            firstTime = time;
-                        }
-                        lastLinkedFile = uri;
-                        break;
-                    }
+                    lastLinkedFile = uri;
+                    break;
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java	(revision 7518)
@@ -56,5 +56,5 @@
         GpxLink link = new GpxLink(webUrl.toString());
         link.type = "web";
-        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
+        wpt.put(GpxConstants.META_LINKS, Collections.singleton(link));
         return wpt;
     }
Index: trunk/src/org/openstreetmap/josm/io/GpxExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxExporter.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/io/GpxExporter.java	(revision 7518)
@@ -90,5 +90,5 @@
         desc.setWrapStyleWord(true);
         desc.setLineWrap(true);
-        desc.setText((String) gpxData.attr.get(META_DESC));
+        desc.setText(gpxData.getString(META_DESC));
         p.add(new JScrollPane(desc), GBC.eop().fill(GBC.BOTH));
 
@@ -120,5 +120,5 @@
         p.add(new JLabel(tr("Keywords")), GBC.eol());
         JosmTextField keywords = new JosmTextField();
-        keywords.setText((String) gpxData.attr.get(META_KEYWORDS));
+        keywords.setText(gpxData.getString(META_KEYWORDS));
         p.add(keywords, GBC.eop().fill(GBC.HORIZONTAL));
 
@@ -155,15 +155,15 @@
         if (author.isSelected()) {
             if (authorName.getText().length() > 0) {
-                gpxData.attr.put(META_AUTHOR_NAME, authorName.getText());
-                gpxData.attr.put(META_COPYRIGHT_AUTHOR, authorName.getText());
+                gpxData.put(META_AUTHOR_NAME, authorName.getText());
+                gpxData.put(META_COPYRIGHT_AUTHOR, authorName.getText());
             }
             if (email.getText().length() > 0) {
-                gpxData.attr.put(META_AUTHOR_EMAIL, email.getText());
+                gpxData.put(META_AUTHOR_EMAIL, email.getText());
             }
             if (copyright.getText().length() > 0) {
-                gpxData.attr.put(META_COPYRIGHT_LICENSE, copyright.getText());
+                gpxData.put(META_COPYRIGHT_LICENSE, copyright.getText());
             }
             if (copyrightYear.getText().length() > 0) {
-                gpxData.attr.put(META_COPYRIGHT_YEAR, copyrightYear.getText());
+                gpxData.put(META_COPYRIGHT_YEAR, copyrightYear.getText());
             }
         }
@@ -171,10 +171,10 @@
         // add the description to the gpx data
         if (desc.getText().length() > 0) {
-            gpxData.attr.put(META_DESC, desc.getText());
+            gpxData.put(META_DESC, desc.getText());
         }
 
         // add keywords to the gpx data
         if (keywords.getText().length() > 0) {
-            gpxData.attr.put(META_KEYWORDS, keywords.getText());
+            gpxData.put(META_KEYWORDS, keywords.getText());
         }
 
@@ -201,5 +201,5 @@
         if (enable) {
             if (copyrightYear.getText().length()==0) {
-                String sCopyrightYear = (String) data.attr.get(META_COPYRIGHT_YEAR);
+                String sCopyrightYear = data.getString(META_COPYRIGHT_YEAR);
                 if (sCopyrightYear == null) {
                     sCopyrightYear = Integer.toString(Calendar.getInstance().get(Calendar.YEAR));
@@ -208,5 +208,5 @@
             }
             if (copyright.getText().length()==0) {
-                String sCopyright = (String) data.attr.get(META_COPYRIGHT_LICENSE);
+                String sCopyright = data.getString(META_COPYRIGHT_LICENSE);
                 if (sCopyright == null) {
                     sCopyright = Main.pref.get("lastCopyright", "https://creativecommons.org/licenses/by-sa/2.5");
@@ -247,10 +247,10 @@
                 emailLabel.setEnabled(b);
                 if (b) {
-                    String sAuthorName = (String) data.attr.get(META_AUTHOR_NAME);
+                    String sAuthorName = data.getString(META_AUTHOR_NAME);
                     if (sAuthorName == null) {
                         sAuthorName = Main.pref.get("lastAuthorName");
                     }
                     authorName.setText(sAuthorName);
-                    String sEmail = (String) data.attr.get(META_AUTHOR_EMAIL);
+                    String sEmail = data.getString(META_AUTHOR_EMAIL);
                     if (sEmail == null) {
                         sEmail = Main.pref.get("lastAuthorEmail");
Index: trunk/src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 7518)
@@ -156,5 +156,5 @@
                     states.push(currentState);
                     currentState = State.copyright;
-                    data.attr.put(META_COPYRIGHT_AUTHOR, atts.getValue("author"));
+                    data.put(META_COPYRIGHT_AUTHOR, atts.getValue("author"));
                     break;
                 case "link":
@@ -172,5 +172,5 @@
                     break;
                 case "email":
-                    data.attr.put(META_AUTHOR_EMAIL, atts.getValue("id") + "@" + atts.getValue("domain"));
+                    data.put(META_AUTHOR_EMAIL, atts.getValue("id") + "@" + atts.getValue("domain"));
                 }
                 break;
@@ -275,29 +275,29 @@
                 switch (localName) {
                 case "name":
-                    data.attr.put(META_NAME, accumulator.toString());
+                    data.put(META_NAME, accumulator.toString());
                     break;
                 case "desc":
-                    data.attr.put(META_DESC, accumulator.toString());
+                    data.put(META_DESC, accumulator.toString());
                     break;
                 case "time":
-                    data.attr.put(META_TIME, accumulator.toString());
+                    data.put(META_TIME, accumulator.toString());
                     break;
                 case "keywords":
-                    data.attr.put(META_KEYWORDS, accumulator.toString());
+                    data.put(META_KEYWORDS, accumulator.toString());
                     break;
                 case "author":
                     if ("1.0".equals(version)) {
                         // author is a string in 1.0, but complex element in 1.1
-                        data.attr.put(META_AUTHOR_NAME, accumulator.toString());
+                        data.put(META_AUTHOR_NAME, accumulator.toString());
                     }
                     break;
                 case "email":
                     if ("1.0".equals(version)) {
-                        data.attr.put(META_AUTHOR_EMAIL, accumulator.toString());
+                        data.put(META_AUTHOR_EMAIL, accumulator.toString());
                     }
                     break;
                 case "url":
                 case "urlname":
-                    data.attr.put(localName, accumulator.toString());
+                    data.put(localName, accumulator.toString());
                     break;
                 case "metadata":
@@ -307,5 +307,5 @@
                         convertUrlToLink(data.attr);
                         if (currentExtensions != null && !currentExtensions.isEmpty()) {
-                            data.attr.put(META_EXTENSIONS, currentExtensions);
+                            data.put(META_EXTENSIONS, currentExtensions);
                         }
                         currentState = states.pop();
@@ -322,5 +322,5 @@
                     break;
                 case "name":
-                    data.attr.put(META_AUTHOR_NAME, accumulator.toString());
+                    data.put(META_AUTHOR_NAME, accumulator.toString());
                     break;
                 case "email":
@@ -328,5 +328,5 @@
                     break;
                 case "link":
-                    data.attr.put(META_AUTHOR_LINK, currentLink);
+                    data.put(META_AUTHOR_LINK, currentLink);
                     break;
                 }
@@ -338,8 +338,8 @@
                     break;
                 case "year":
-                    data.attr.put(META_COPYRIGHT_YEAR, accumulator.toString());
+                    data.put(META_COPYRIGHT_YEAR, accumulator.toString());
                     break;
                 case "license":
-                    data.attr.put(META_COPYRIGHT_LICENSE, accumulator.toString());
+                    data.put(META_COPYRIGHT_LICENSE, accumulator.toString());
                     break;
                 }
@@ -361,5 +361,5 @@
                 }
                 if (currentState == State.author) {
-                    data.attr.put(META_AUTHOR_LINK, currentLink);
+                    data.put(META_AUTHOR_LINK, currentLink);
                 } else if (currentState != State.link) {
                     Map<String, Object> attr = getAttr();
@@ -381,5 +381,5 @@
                 case "url":
                 case "urlname":
-                    currentWayPoint.attr.put(localName, accumulator.toString());
+                    currentWayPoint.put(localName, accumulator.toString());
                     break;
                 case "hdop":
@@ -387,16 +387,16 @@
                 case "pdop":
                     try {
-                        currentWayPoint.attr.put(localName, Float.parseFloat(accumulator.toString()));
+                        currentWayPoint.put(localName, Float.parseFloat(accumulator.toString()));
                     } catch(Exception e) {
-                        currentWayPoint.attr.put(localName, new Float(0));
+                        currentWayPoint.put(localName, new Float(0));
                     }
                     break;
                 case "time":
-                    currentWayPoint.attr.put(localName, accumulator.toString());
+                    currentWayPoint.put(localName, accumulator.toString());
                     currentWayPoint.setTime();
                     break;
                 case "cmt":
                 case "desc":
-                    currentWayPoint.attr.put(localName, accumulator.toString());
+                    currentWayPoint.put(localName, accumulator.toString());
                     currentWayPoint.setTime();
                     break;
@@ -415,5 +415,5 @@
                     convertUrlToLink(currentWayPoint.attr);
                     if (currentExtensions != null && !currentExtensions.isEmpty()) {
-                        currentWayPoint.attr.put(META_EXTENSIONS, currentExtensions);
+                        currentWayPoint.put(META_EXTENSIONS, currentExtensions);
                     }
                     data.waypoints.add(currentWayPoint);
@@ -472,5 +472,5 @@
             if (!states.empty())
                 throw new SAXException(tr("Parse error: invalid document structure for GPX document."));
-            Extensions metaExt = (Extensions) data.attr.get(META_EXTENSIONS);
+            Extensions metaExt = (Extensions) data.get(META_EXTENSIONS);
             if (metaExt != null && "true".equals(metaExt.get("from-server"))) {
                 data.fromServer = true;
Index: trunk/src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 7518)
@@ -10,4 +10,5 @@
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -32,8 +33,16 @@
 public class GpxWriter extends XmlWriter implements GpxConstants {
 
+    /**
+     * Constructs a new {@code GpxWriter}.
+     * @param out The output writer
+     */
     public GpxWriter(PrintWriter out) {
         super(out);
     }
 
+    /**
+     * Constructs a new {@code GpxWriter}.
+     * @param out The output stream
+     */
     public GpxWriter(OutputStream out) {
         super(new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8))));
@@ -47,4 +56,8 @@
     private static final int TRACK_POINT = 2;
 
+    /**
+     * Writes the given GPX data.
+     * @param data The data to write
+     */
     public void write(GpxData data) {
         this.data = data;
@@ -80,9 +93,8 @@
     }
 
-    private void writeAttr(IWithAttributes obj) {
-        for (String key : WPT_KEYS) {
+    private void writeAttr(IWithAttributes obj, List<String> keys) {
+        for (String key : keys) {
             if (key.equals(META_LINKS)) {
-                @SuppressWarnings("unchecked")
-                Collection<GpxLink> lValue = (Collection<GpxLink>) obj.getCollection(key);
+                Collection<GpxLink> lValue = obj.<GpxLink>getCollection(key);
                 if (lValue != null) {
                     for (GpxLink link : lValue) {
@@ -104,5 +116,4 @@
     }
 
-    @SuppressWarnings("unchecked")
     private void writeMetaData() {
         Map<String, Object> attr = data.attr;
@@ -111,5 +122,5 @@
         // write the description
         if (attr.containsKey(META_DESC)) {
-            simpleTag("desc", (String)attr.get(META_DESC));
+            simpleTag("desc", data.getString(META_DESC));
         }
 
@@ -119,8 +130,8 @@
             openln("author");
             // write the name
-            simpleTag("name", (String) attr.get(META_AUTHOR_NAME));
+            simpleTag("name", data.getString(META_AUTHOR_NAME));
             // write the email address
             if (attr.containsKey(META_AUTHOR_EMAIL)) {
-                String[] tmp = ((String)attr.get(META_AUTHOR_EMAIL)).split("@");
+                String[] tmp = data.getString(META_AUTHOR_EMAIL).split("@");
                 if (tmp.length == 2) {
                     inline("email", "id=\"" + tmp[0] + "\" domain=\""+tmp[1]+"\"");
@@ -128,5 +139,5 @@
             }
             // write the author link
-            gpxLink((GpxLink) attr.get(META_AUTHOR_LINK));
+            gpxLink((GpxLink) data.get(META_AUTHOR_LINK));
             closeln("author");
         }
@@ -135,10 +146,10 @@
         if (attr.containsKey(META_COPYRIGHT_LICENSE)
                 || attr.containsKey(META_COPYRIGHT_YEAR)) {
-            openAtt("copyright", "author=\""+ attr.get(META_COPYRIGHT_AUTHOR) +"\"");
+            openAtt("copyright", "author=\""+ data.get(META_COPYRIGHT_AUTHOR) +"\"");
             if (attr.containsKey(META_COPYRIGHT_YEAR)) {
-                simpleTag("year", (String) attr.get(META_COPYRIGHT_YEAR));
+                simpleTag("year", (String) data.get(META_COPYRIGHT_YEAR));
             }
             if (attr.containsKey(META_COPYRIGHT_LICENSE)) {
-                simpleTag("license", encode((String) attr.get(META_COPYRIGHT_LICENSE)));
+                simpleTag("license", encode((String) data.get(META_COPYRIGHT_LICENSE)));
             }
             closeln("copyright");
@@ -147,5 +158,5 @@
         // write links
         if (attr.containsKey(META_LINKS)) {
-            for (GpxLink link : (Collection<GpxLink>) attr.get(META_LINKS)) {
+            for (GpxLink link : data.<GpxLink>getCollection(META_LINKS)) {
                 gpxLink(link);
             }
@@ -154,5 +165,5 @@
         // write keywords
         if (attr.containsKey(META_KEYWORDS)) {
-            simpleTag("keywords", (String)attr.get(META_KEYWORDS));
+            simpleTag("keywords", data.getString(META_KEYWORDS));
         }
 
@@ -182,5 +193,5 @@
         for (GpxRoute rte : data.routes) {
             openln("rte");
-            writeAttr(rte);
+            writeAttr(rte, RTE_TRK_KEYS);
             for (WayPoint pnt : rte.routePoints) {
                 wayPoint(pnt, ROUTE_POINT);
@@ -193,5 +204,5 @@
         for (GpxTrack trk : data.tracks) {
             openln("trk");
-            writeAttr(trk);
+            writeAttr(trk, RTE_TRK_KEYS);
             for (GpxTrackSegment seg : trk.getSegments()) {
                 openln("trkseg");
@@ -284,5 +295,5 @@
             } else {
                 openAtt(type, coordAttr);
-                writeAttr(pnt);
+                writeAttr(pnt, WPT_KEYS);
                 closeln(type);
             }
Index: trunk/src/org/openstreetmap/josm/io/NmeaReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/NmeaReader.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/io/NmeaReader.java	(revision 7518)
@@ -15,4 +15,5 @@
 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.GpxData;
 import org.openstreetmap.josm.data.gpx.ImmutableGpxTrack;
@@ -287,5 +288,5 @@
                     // As this sentence has no complete time only use it
                     // if there is no time so far
-                    currentwp.attr.put("time", DateUtils.fromDate(d));
+                    currentwp.put(GpxConstants.PT_TIME, DateUtils.fromDate(d));
                 }
                 // elevation
@@ -299,5 +300,5 @@
                         // device sends nonstandard data.
                         if(!accu.isEmpty()) { // FIX ? same check
-                            currentwp.attr.put("ele", accu);
+                            currentwp.put(GpxConstants.PT_ELE, accu);
                         }
                     }
@@ -308,10 +309,10 @@
                 if(!accu.isEmpty()) {
                     sat = Integer.parseInt(accu);
-                    currentwp.attr.put("sat", accu);
+                    currentwp.put(GpxConstants.PT_SAT, accu);
                 }
                 // h-dilution
                 accu=e[GPGGA.HDOP.position];
                 if(!accu.isEmpty()) {
-                    currentwp.attr.put("hdop", Float.parseFloat(accu));
+                    currentwp.put(GpxConstants.PT_HDOP, Float.parseFloat(accu));
                 }
                 // fix
@@ -321,15 +322,15 @@
                     switch(fixtype) {
                     case 0:
-                        currentwp.attr.put("fix", "none");
+                        currentwp.put(GpxConstants.PT_FIX, "none");
                         break;
                     case 1:
                         if(sat < 4) {
-                            currentwp.attr.put("fix", "2d");
+                            currentwp.put(GpxConstants.PT_FIX, "2d");
                         } else {
-                            currentwp.attr.put("fix", "3d");
+                            currentwp.put(GpxConstants.PT_FIX, "3d");
                         }
                         break;
                     case 2:
-                        currentwp.attr.put("fix", "dgps");
+                        currentwp.put(GpxConstants.PT_FIX, "dgps");
                         break;
                     default:
@@ -345,5 +346,5 @@
                     if(!accu.isEmpty()) {
                         Double.parseDouble(accu);
-                        currentwp.attr.put("course", accu);
+                        currentwp.put("course", accu);
                     }
                 }
@@ -355,5 +356,5 @@
                         double speed = Double.parseDouble(accu);
                         speed /= 3.6; // speed in m/s
-                        currentwp.attr.put("speed", Double.toString(speed));
+                        currentwp.put("speed", Double.toString(speed));
                     }
                 }
@@ -362,15 +363,15 @@
                 accu=e[GPGSA.VDOP.position];
                 if(!accu.isEmpty()) {
-                    currentwp.attr.put("vdop", Float.parseFloat(accu));
+                    currentwp.put(GpxConstants.PT_VDOP, Float.parseFloat(accu));
                 }
                 // hdop
                 accu=e[GPGSA.HDOP.position];
                 if(!accu.isEmpty()) {
-                    currentwp.attr.put("hdop", Float.parseFloat(accu));
+                    currentwp.put(GpxConstants.PT_HDOP, Float.parseFloat(accu));
                 }
                 // pdop
                 accu=e[GPGSA.PDOP.position];
                 if(!accu.isEmpty()) {
-                    currentwp.attr.put("pdop", Float.parseFloat(accu));
+                    currentwp.put(GpxConstants.PT_PDOP, Float.parseFloat(accu));
                 }
             }
@@ -399,5 +400,5 @@
                 }
                 // time: this sentence has complete time so always use it.
-                currentwp.attr.put("time", DateUtils.fromDate(d));
+                currentwp.put(GpxConstants.PT_TIME, DateUtils.fromDate(d));
                 // speed
                 accu = e[GPRMC.SPEED.position];
@@ -405,5 +406,5 @@
                     double speed = Double.parseDouble(accu);
                     speed *= 0.514444444; // to m/s
-                    currentwp.attr.put("speed", Double.toString(speed));
+                    currentwp.put("speed", Double.toString(speed));
                 }
                 // course
@@ -411,5 +412,5 @@
                 if(!accu.isEmpty() && !currentwp.attr.containsKey("course")) {
                     Double.parseDouble(accu);
-                    currentwp.attr.put("course", accu);
+                    currentwp.put("course", accu);
                 }
 
Index: trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java	(revision 7517)
+++ trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java	(revision 7518)
@@ -100,5 +100,5 @@
         public void write(MarkerLayer layer) {
             GpxData data = new GpxData();
-            data.attr.put(GpxData.META_DESC, "exported JOSM marker layer");
+            data.put(GpxData.META_DESC, "exported JOSM marker layer");
             for (Marker m : layer.data) {
                 data.waypoints.add(m.convertToWayPoint());
