Index: trunk/src/org/openstreetmap/josm/command/PurgeCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/PurgeCommand.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/command/PurgeCommand.java	(revision 5681)
@@ -154,82 +154,81 @@
          * Then add all ways, each preceded by its (remaining) nodes.
          */
-        top:
-            while (!in.isEmpty()) {
-                for (Iterator<OsmPrimitive> it = in.iterator(); it.hasNext();) {
-                    OsmPrimitive u = it.next();
-                    if (u instanceof Way) {
-                        Way w = (Way) u;
-                        it.remove();
-                        for (Node n : w.getNodes()) {
-                            if (in.contains(n)) {
-                                in.remove(n);
-                                out.add(n);
-                            }
+        top: while (!in.isEmpty()) {
+            for (Iterator<OsmPrimitive> it = in.iterator(); it.hasNext();) {
+                OsmPrimitive u = it.next();
+                if (u instanceof Way) {
+                    Way w = (Way) u;
+                    it.remove();
+                    for (Node n : w.getNodes()) {
+                        if (in.contains(n)) {
+                            in.remove(n);
+                            out.add(n);
                         }
-                        out.add(w);
-                        continue top;
-                    }
-                }
-                break; // no more ways left
-            }
-
-            /**
-             * Rest are relations. Do topological sorting on a DAG where each
-             * arrow points from child to parent. (Because it is faster to
-             * loop over getReferrers() than getMembers().)
-             */
-            Set<Relation> inR = (Set) in;
-            Set<Relation> childlessR = new HashSet<Relation>();
-            List<Relation> outR = new ArrayList<Relation>(inR.size());
-
-            HashMap<Relation, Integer> numChilds = new HashMap<Relation, Integer>();
-
-            // calculate initial number of childs
-            for (Relation r : inR) {
-                numChilds.put(r, 0);
-            }
-            for (Relation r : inR) {
-                for (OsmPrimitive parent : r.getReferrers()) {
-                    if (!(parent instanceof Relation))
-                        throw new AssertionError();
-                    Integer i = numChilds.get(parent);
-                    if (i != null) {
-                        numChilds.put((Relation)parent, i+1);
-                    }
-                }
-            }
-            for (Relation r : inR) {
-                if (numChilds.get(r).equals(0)) {
-                    childlessR.add(r);
-                }
-            }
-
-            while (!childlessR.isEmpty()) {
-                // Identify one childless Relation and
-                // let it virtually die. This makes other
-                // relations childless.
-                Iterator<Relation> it  = childlessR.iterator();
-                Relation next = it.next();
-                it.remove();
-                outR.add(next);
-
-                for (OsmPrimitive parentPrim : next.getReferrers()) {
-                    Relation parent = (Relation) parentPrim;
-                    Integer i = numChilds.get(parent);
-                    if (i != null) {
-                        numChilds.put(parent, i-1);
-                        if (i-1 == 0) {
-                            childlessR.add(parent);
-                        }
-                    }
-                }
-            }
-
-            if (outR.size() != inR.size())
-                throw new AssertionError("topo sort algorithm failed");
-
-            out.addAll(outR);
-
-            return out;
+                    }
+                    out.add(w);
+                    continue top;
+                }
+            }
+            break; // no more ways left
+        }
+
+        /**
+            * Rest are relations. Do topological sorting on a DAG where each
+            * arrow points from child to parent. (Because it is faster to
+            * loop over getReferrers() than getMembers().)
+            */
+        Set<Relation> inR = (Set) in;
+        Set<Relation> childlessR = new HashSet<Relation>();
+        List<Relation> outR = new ArrayList<Relation>(inR.size());
+
+        HashMap<Relation, Integer> numChilds = new HashMap<Relation, Integer>();
+
+        // calculate initial number of childs
+        for (Relation r : inR) {
+            numChilds.put(r, 0);
+        }
+        for (Relation r : inR) {
+            for (OsmPrimitive parent : r.getReferrers()) {
+                if (!(parent instanceof Relation))
+                    throw new AssertionError();
+                Integer i = numChilds.get(parent);
+                if (i != null) {
+                    numChilds.put((Relation)parent, i+1);
+                }
+            }
+        }
+        for (Relation r : inR) {
+            if (numChilds.get(r).equals(0)) {
+                childlessR.add(r);
+            }
+        }
+
+        while (!childlessR.isEmpty()) {
+            // Identify one childless Relation and
+            // let it virtually die. This makes other
+            // relations childless.
+            Iterator<Relation> it  = childlessR.iterator();
+            Relation next = it.next();
+            it.remove();
+            outR.add(next);
+
+            for (OsmPrimitive parentPrim : next.getReferrers()) {
+                Relation parent = (Relation) parentPrim;
+                Integer i = numChilds.get(parent);
+                if (i != null) {
+                    numChilds.put(parent, i-1);
+                    if (i-1 == 0) {
+                        childlessR.add(parent);
+                    }
+                }
+            }
+        }
+
+        if (outR.size() != inR.size())
+            throw new AssertionError("topo sort algorithm failed");
+
+        out.addAll(outR);
+
+        return out;
     }
 
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 5681)
@@ -0,0 +1,32 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.gpx;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Constants for GPX handling.
+ */
+public interface GpxConstants {
+
+    public static final String META_PREFIX = "meta.";
+    public static final String META_AUTHOR_NAME = META_PREFIX + "author.name";
+    public static final String META_AUTHOR_EMAIL = META_PREFIX + "author.email";
+    public static final String META_AUTHOR_LINK = META_PREFIX + "author.link";
+    public static final String META_COPYRIGHT_AUTHOR = META_PREFIX + "copyright.author";
+    public static final String META_COPYRIGHT_LICENSE = META_PREFIX + "copyright.license";
+    public static final String META_COPYRIGHT_YEAR = META_PREFIX + "copyright.year";
+    public static final String META_DESC = META_PREFIX + "desc";
+    public static final String META_KEYWORDS = META_PREFIX + "keywords";
+    public static final String META_LINKS = META_PREFIX + "links";
+    public static final String META_NAME = META_PREFIX + "name";
+    public static final String META_TIME = META_PREFIX + "time";
+    public static final String META_EXTENSIONS = META_PREFIX + "extensions";
+
+    public static final String JOSM_EXTENSIONS_NAMESPACE_URI = "http://josm.openstreetmap.de/gpx-extensions";
+
+    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");
+
+}
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 5681)
@@ -18,20 +18,4 @@
  */
 public class GpxData extends WithAttributes {
-
-    public static final String META_PREFIX = "meta.";
-    public static final String META_AUTHOR_NAME = META_PREFIX + "author.name";
-    public static final String META_AUTHOR_EMAIL = META_PREFIX + "author.email";
-    public static final String META_AUTHOR_LINK = META_PREFIX + "author.link";
-    public static final String META_COPYRIGHT_AUTHOR = META_PREFIX + "copyright.author";
-    public static final String META_COPYRIGHT_LICENSE = META_PREFIX + "copyright.license";
-    public static final String META_COPYRIGHT_YEAR = META_PREFIX + "copyright.year";
-    public static final String META_DESC = META_PREFIX + "desc";
-    public static final String META_KEYWORDS = META_PREFIX + "keywords";
-    public static final String META_LINKS = META_PREFIX + "links";
-    public static final String META_NAME = META_PREFIX + "name";
-    public static final String META_TIME = META_PREFIX + "time";
-    public static final String META_EXTENSIONS = META_PREFIX + "extensions";
-
-    public static final String JOSM_EXTENSIONS_NAMESPACE_URI = "http://josm.openstreetmap.de/gpx-extensions";
 
     public File storageFile;
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxTrack.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxTrack.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxTrack.java	(revision 5681)
@@ -15,5 +15,5 @@
  */
 
-public interface GpxTrack {
+public interface GpxTrack extends IWithAttributes {
 
     Collection<GpxTrackSegment> getSegments();
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 5681)
@@ -0,0 +1,31 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.gpx;
+
+import java.util.Collection;
+
+/**
+ * Object with attributes.
+ */
+public interface IWithAttributes {
+
+    /**
+     * Returns the String value to which the specified key is mapped, 
+     * or {@code null} if this map contains no String mapping for the key.
+     *  
+     * @param key the key whose associated value is to be returned
+     * @return the String value to which the specified key is mapped, 
+     *         or {@code null} if this map contains no String mapping for the key
+     */
+    String getString(String key);
+    
+    /**
+     * 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, 
+     *         or {@code null} if this map contains no Collection mapping for the key
+     * @since 5502
+     */
+    Collection<?> getCollection(String key);
+}
Index: trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java	(revision 5681)
@@ -11,7 +11,6 @@
 import org.openstreetmap.josm.data.Bounds;
 
-public class ImmutableGpxTrack implements GpxTrack {
+public class ImmutableGpxTrack extends WithAttributes implements GpxTrack {
 
-    private final Map<String, Object> attributes;
     private final Collection<GpxTrackSegment> segments;
     private final double length;
@@ -25,5 +24,5 @@
             }
         }
-        this.attributes = Collections.unmodifiableMap(new HashMap<String, Object>(attributes));
+        this.attr = Collections.unmodifiableMap(new HashMap<String, Object>(attributes));
         this.segments = Collections.unmodifiableCollection(newSegments);
         this.length = calculateLength();
@@ -55,8 +54,10 @@
     }
 
+    @Override
     public Map<String, Object> getAttributes() {
-        return attributes;
+        return attr;
     }
 
+    @Override
     public Bounds getBounds() {
         if (bounds == null)
@@ -66,12 +67,15 @@
     }
 
+    @Override
     public double length() {
         return length;
     }
 
+    @Override
     public Collection<GpxTrackSegment> getSegments() {
         return segments;
     }
 
+    @Override
     public int getUpdateCount() {
         return 0;
Index: trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java	(revision 5681)
@@ -1,3 +1,3 @@
-// License: GPL.
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.data.gpx;
 
@@ -7,4 +7,6 @@
 
 /**
+ * Default implementation for IWithAttributes.
+ *
  * Base class for various classes in the GPX model.
  *
@@ -12,5 +14,5 @@
  * @since 444
  */
-public class WithAttributes {
+public class WithAttributes implements IWithAttributes, GpxConstants {
 
     /**
@@ -20,25 +22,27 @@
 
     /**
-     * Returns the String value to which the specified key is mapped, 
+     * Returns the String value to which the specified key is mapped,
      * or {@code null} if this map contains no String mapping for the key.
-     *  
+     *
      * @param key the key whose associated value is to be returned
-     * @return the String value to which the specified key is mapped, 
+     * @return the String value to which the specified key is mapped,
      *         or {@code null} if this map contains no String mapping for the key
      */
+    @Override
     public String getString(String key) {
         Object value = attr.get(key);
         return (value instanceof String) ? (String)value : null;
     }
-    
+
     /**
-     * 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
      */
+    @Override
     public Collection<?> getCollection(String key) {
         Object value = attr.get(key);
Index: trunk/src/org/openstreetmap/josm/data/validation/PaintVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/PaintVisitor.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/data/validation/PaintVisitor.java	(revision 5681)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.data.validation;
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 5681)
@@ -68,4 +68,5 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 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.GpxRoute;
@@ -207,9 +208,9 @@
 
         if (data.attr.containsKey("name")) {
-            info.append(tr("Name: {0}", data.attr.get(GpxData.META_NAME))).append("<br>");
+            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(GpxData.META_DESC))).append("<br>");
+            info.append(tr("Description: {0}", data.attr.get(GpxConstants.META_DESC))).append("<br>");
         }
 
@@ -324,9 +325,9 @@
 
         if (data.attr.containsKey("name")) {
-            info.append(tr("Name: {0}", data.attr.get(GpxData.META_NAME))).append("<br>");
+            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(GpxData.META_DESC))).append("<br>");
+            info.append(tr("Description: {0}", data.attr.get(GpxConstants.META_DESC))).append("<br>");
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 5681)
@@ -23,5 +23,5 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.gpx.GpxData;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxLink;
 import org.openstreetmap.josm.data.gpx.WayPoint;
@@ -185,5 +185,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(GpxData.META_LINKS);
+                Collection<GpxLink> links = (Collection<GpxLink>)wpt.attr.get(GpxConstants.META_LINKS);
                 if (links != null) {
                     for (GpxLink oneLink : links ) {
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 5681)
@@ -32,4 +32,5 @@
 import org.openstreetmap.josm.data.Bounds;
 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;
@@ -85,8 +86,8 @@
             /* calculate time differences in waypoints */
             double time = wpt.time;
-            boolean wpt_has_link = wpt.attr.containsKey(GpxData.META_LINKS);
+            boolean wpt_has_link = wpt.attr.containsKey(GpxConstants.META_LINKS);
             if (firstTime < 0 && wpt_has_link) {
                 firstTime = time;
-                for (Object oneLink : wpt.getCollection(GpxData.META_LINKS)) {
+                for (Object oneLink : wpt.getCollection(GpxConstants.META_LINKS)) {
                     if (oneLink instanceof GpxLink) {
                         lastLinkedFile = ((GpxLink)oneLink).uri;
@@ -96,5 +97,5 @@
             }
             if (wpt_has_link) {
-                for (Object oneLink : wpt.getCollection(GpxData.META_LINKS)) {
+                for (Object oneLink : wpt.getCollection(GpxConstants.META_LINKS)) {
                     if (oneLink instanceof GpxLink) {
                         String uri = ((GpxLink)oneLink).uri;
Index: trunk/src/org/openstreetmap/josm/io/GpxExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxExporter.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/io/GpxExporter.java	(revision 5681)
@@ -27,4 +27,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -36,5 +37,5 @@
 import org.openstreetmap.josm.tools.GBC;
 
-public class GpxExporter extends FileExporter {
+public class GpxExporter extends FileExporter implements GpxConstants {
     private final static String warningGpl = "<html><font color='red' size='-2'>"
         + tr("Note: GPL is not compatible with the OSM license. Do not upload GPL licensed tracks.") + "</html>";
@@ -82,5 +83,5 @@
         desc.setWrapStyleWord(true);
         desc.setLineWrap(true);
-        desc.setText((String) gpxData.attr.get(GpxData.META_DESC));
+        desc.setText((String) gpxData.attr.get(META_DESC));
         p.add(new JScrollPane(desc), GBC.eop().fill(GBC.BOTH));
 
@@ -112,5 +113,5 @@
         p.add(new JLabel(tr("Keywords")), GBC.eol());
         JTextField keywords = new JTextField();
-        keywords.setText((String) gpxData.attr.get(GpxData.META_KEYWORDS));
+        keywords.setText((String) gpxData.attr.get(META_KEYWORDS));
         p.add(keywords, GBC.eop().fill(GBC.HORIZONTAL));
 
@@ -144,15 +145,15 @@
         if (author.isSelected()) {
             if (authorName.getText().length() > 0) {
-                gpxData.attr.put(GpxData.META_AUTHOR_NAME, authorName.getText());
-                gpxData.attr.put(GpxData.META_COPYRIGHT_AUTHOR, authorName.getText());
+                gpxData.attr.put(META_AUTHOR_NAME, authorName.getText());
+                gpxData.attr.put(META_COPYRIGHT_AUTHOR, authorName.getText());
             }
             if (email.getText().length() > 0) {
-                gpxData.attr.put(GpxData.META_AUTHOR_EMAIL, email.getText());
+                gpxData.attr.put(META_AUTHOR_EMAIL, email.getText());
             }
             if (copyright.getText().length() > 0) {
-                gpxData.attr.put(GpxData.META_COPYRIGHT_LICENSE, copyright.getText());
+                gpxData.attr.put(META_COPYRIGHT_LICENSE, copyright.getText());
             }
             if (copyrightYear.getText().length() > 0) {
-                gpxData.attr.put(GpxData.META_COPYRIGHT_YEAR, copyrightYear.getText());
+                gpxData.attr.put(META_COPYRIGHT_YEAR, copyrightYear.getText());
             }
         }
@@ -160,10 +161,10 @@
         // add the description to the gpx data
         if (desc.getText().length() > 0) {
-            gpxData.attr.put(GpxData.META_DESC, desc.getText());
+            gpxData.attr.put(META_DESC, desc.getText());
         }
 
         // add keywords to the gpx data
         if (keywords.getText().length() > 0) {
-            gpxData.attr.put(GpxData.META_KEYWORDS, keywords.getText());
+            gpxData.attr.put(META_KEYWORDS, keywords.getText());
         }
 
@@ -193,5 +194,5 @@
         if (enable) {
             if (copyrightYear.getText().length()==0) {
-                String sCopyrightYear = (String) data.attr.get(GpxData.META_COPYRIGHT_YEAR);
+                String sCopyrightYear = (String) data.attr.get(META_COPYRIGHT_YEAR);
                 if (sCopyrightYear == null) {
                     sCopyrightYear = Integer.toString(Calendar.getInstance().get(Calendar.YEAR));
@@ -200,5 +201,5 @@
             }
             if (copyright.getText().length()==0) {
-                String sCopyright = (String) data.attr.get(GpxData.META_COPYRIGHT_LICENSE);
+                String sCopyright = (String) data.attr.get(META_COPYRIGHT_LICENSE);
                 if (sCopyright == null) {
                     sCopyright = Main.pref.get("lastCopyright", "http://creativecommons.org/licenses/by-sa/2.5");
@@ -243,10 +244,10 @@
                 emailLabel.setEnabled(b);
                 if (b) {
-                    String sAuthorName = (String) data.attr.get(GpxData.META_AUTHOR_NAME);
+                    String sAuthorName = (String) data.attr.get(META_AUTHOR_NAME);
                     if (sAuthorName == null) {
                         sAuthorName = Main.pref.get("lastAuthorName");
                     }
                     authorName.setText(sAuthorName);
-                    String sEmail = (String) data.attr.get(GpxData.META_AUTHOR_EMAIL);
+                    String sEmail = (String) data.attr.get(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 5680)
+++ trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 5681)
@@ -21,4 +21,5 @@
 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;
 import org.openstreetmap.josm.data.gpx.GpxLink;
@@ -39,5 +40,5 @@
  * @author imi, ramack
  */
-public class GpxReader {
+public class GpxReader implements GpxConstants {
 
     private String version;
@@ -140,5 +141,5 @@
                     states.push(currentState);
                     currentState = State.copyright;
-                    data.attr.put(GpxData.META_COPYRIGHT_AUTHOR, atts.getValue("author"));
+                    data.attr.put(META_COPYRIGHT_AUTHOR, atts.getValue("author"));
                 } else if (localName.equals("link")) {
                     states.push(currentState);
@@ -153,5 +154,5 @@
                     currentLink = new GpxLink(atts.getValue("href"));
                 } else if (localName.equals("email")) {
-                    data.attr.put(GpxData.META_AUTHOR_EMAIL, atts.getValue("id") + "@" + atts.getValue("domain"));
+                    data.attr.put(META_AUTHOR_EMAIL, atts.getValue("id") + "@" + atts.getValue("domain"));
                 }
                 break;
@@ -243,16 +244,16 @@
             case metadata:  // GPX 1.1
                 if (localName.equals("name")) {
-                    data.attr.put(GpxData.META_NAME, accumulator.toString());
+                    data.attr.put(META_NAME, accumulator.toString());
                 } else if (localName.equals("desc")) {
-                    data.attr.put(GpxData.META_DESC, accumulator.toString());
+                    data.attr.put(META_DESC, accumulator.toString());
                 } else if (localName.equals("time")) {
-                    data.attr.put(GpxData.META_TIME, accumulator.toString());
+                    data.attr.put(META_TIME, accumulator.toString());
                 } else if (localName.equals("keywords")) {
-                    data.attr.put(GpxData.META_KEYWORDS, accumulator.toString());
+                    data.attr.put(META_KEYWORDS, accumulator.toString());
                 } else if (version.equals("1.0") && localName.equals("author")) {
                     // author is a string in 1.0, but complex element in 1.1
-                    data.attr.put(GpxData.META_AUTHOR_NAME, accumulator.toString());
+                    data.attr.put(META_AUTHOR_NAME, accumulator.toString());
                 } else if (version.equals("1.0") && localName.equals("email")) {
-                    data.attr.put(GpxData.META_AUTHOR_EMAIL, accumulator.toString());
+                    data.attr.put(META_AUTHOR_EMAIL, accumulator.toString());
                 } else if (localName.equals("url") || localName.equals("urlname")) {
                     data.attr.put(localName, accumulator.toString());
@@ -261,5 +262,5 @@
                     convertUrlToLink(data.attr);
                     if (currentExtensions != null && !currentExtensions.isEmpty()) {
-                        data.attr.put(GpxData.META_EXTENSIONS, currentExtensions);
+                        data.attr.put(META_EXTENSIONS, currentExtensions);
                     }
                     currentState = states.pop();
@@ -271,9 +272,9 @@
                     currentState = states.pop();
                 } else if (localName.equals("name")) {
-                    data.attr.put(GpxData.META_AUTHOR_NAME, accumulator.toString());
+                    data.attr.put(META_AUTHOR_NAME, accumulator.toString());
                 } else if (localName.equals("email")) {
                     // do nothing, has been parsed on startElement
                 } else if (localName.equals("link")) {
-                    data.attr.put(GpxData.META_AUTHOR_LINK, currentLink);
+                    data.attr.put(META_AUTHOR_LINK, currentLink);
                 }
                 break;
@@ -282,7 +283,7 @@
                     currentState = states.pop();
                 } else if (localName.equals("year")) {
-                    data.attr.put(GpxData.META_COPYRIGHT_YEAR, accumulator.toString());
+                    data.attr.put(META_COPYRIGHT_YEAR, accumulator.toString());
                 } else if (localName.equals("license")) {
-                    data.attr.put(GpxData.META_COPYRIGHT_LICENSE, accumulator.toString());
+                    data.attr.put(META_COPYRIGHT_LICENSE, accumulator.toString());
                 }
                 break;
@@ -299,11 +300,11 @@
                 }
                 if (currentState == State.author) {
-                    data.attr.put(GpxData.META_AUTHOR_LINK, currentLink);
+                    data.attr.put(META_AUTHOR_LINK, currentLink);
                 } else if (currentState != State.link) {
                     Map<String, Object> attr = getAttr();
-                    if (!attr.containsKey(GpxData.META_LINKS)) {
-                        attr.put(GpxData.META_LINKS, new LinkedList<GpxLink>());
+                    if (!attr.containsKey(META_LINKS)) {
+                        attr.put(META_LINKS, new LinkedList<GpxLink>());
                     }
-                    ((Collection<GpxLink>) attr.get(GpxData.META_LINKS)).add(currentLink);
+                    ((Collection<GpxLink>) attr.get(META_LINKS)).add(currentLink);
                 }
                 break;
@@ -364,5 +365,5 @@
                     currentState = states.pop();
                 // only interested in extensions written by JOSM
-                } else if (GpxData.JOSM_EXTENSIONS_NAMESPACE_URI.equals(namespaceURI)) {
+                } else if (JOSM_EXTENSIONS_NAMESPACE_URI.equals(namespaceURI)) {
                     currentExtensions.put(localName, accumulator.toString());
                 }
@@ -382,5 +383,5 @@
             if (!states.empty())
                 throw new SAXException(tr("Parse error: invalid document structure for GPX document."));
-            Extensions metaExt = (Extensions) data.attr.get(GpxData.META_EXTENSIONS);
+            Extensions metaExt = (Extensions) data.attr.get(META_EXTENSIONS);
             if (metaExt != null && "true".equals(metaExt.get("from-server"))) {
                 data.fromServer = true;
@@ -396,11 +397,11 @@
             String urlname = (String) attr.get("urlname");
             if (url != null) {
-                if (!attr.containsKey(GpxData.META_LINKS)) {
-                    attr.put(GpxData.META_LINKS, new LinkedList<GpxLink>());
+                if (!attr.containsKey(META_LINKS)) {
+                    attr.put(META_LINKS, new LinkedList<GpxLink>());
                 }
                 GpxLink link = new GpxLink(url);
                 link.text = urlname;
                 @SuppressWarnings("unchecked")
-                Collection<GpxLink> links = (Collection) attr.get(GpxData.META_LINKS);
+                Collection<GpxLink> links = (Collection) attr.get(META_LINKS);
                 links.add(link);
             }
Index: trunk/src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 5680)
+++ trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 5681)
@@ -9,11 +9,10 @@
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
 import java.util.Collection;
-import java.util.List;
 import java.util.Map;
 
 import org.openstreetmap.josm.data.Bounds;
 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;
@@ -26,5 +25,5 @@
  * Writes GPX files from GPX data or OSM data.
  */
-public class GpxWriter extends XmlWriter {
+public class GpxWriter extends XmlWriter implements GpxConstants {
 
     public GpxWriter(PrintWriter out) {
@@ -52,5 +51,5 @@
         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", GpxData.JOSM_EXTENSIONS_NAMESPACE_URI) : "") +
+                (data.fromServer ? 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\">");
@@ -64,7 +63,4 @@
     }
 
-    public static List<String> WPT_KEYS = Arrays.asList("ele", "time", "magvar", "geoidheight",
-            "name", "cmt", "desc", "src", GpxData.META_LINKS, "sym", "number", "type",
-            "fix", "sat", "hdop", "vdop", "pdop", "ageofdgpsdata", "dgpsid");
     @SuppressWarnings("unchecked")
     private void writeAttr(Map<String, Object> attr) {
@@ -72,5 +68,5 @@
             Object value = attr.get(key);
             if (value != null) {
-                if (key.equals(GpxData.META_LINKS)) {
+                if (key.equals(META_LINKS)) {
                     for (GpxLink link : (Collection<GpxLink>) value) {
                         gpxLink(link);
@@ -89,17 +85,17 @@
 
         // write the description
-        if (attr.containsKey(GpxData.META_DESC)) {
-            simpleTag("desc", (String)attr.get(GpxData.META_DESC));
+        if (attr.containsKey(META_DESC)) {
+            simpleTag("desc", (String)attr.get(META_DESC));
         }
 
         // write the author details
-        if (attr.containsKey(GpxData.META_AUTHOR_NAME)
-                || attr.containsKey(GpxData.META_AUTHOR_EMAIL)) {
+        if (attr.containsKey(META_AUTHOR_NAME)
+                || attr.containsKey(META_AUTHOR_EMAIL)) {
             openln("author");
             // write the name
-            simpleTag("name", (String) attr.get(GpxData.META_AUTHOR_NAME));
+            simpleTag("name", (String) attr.get(META_AUTHOR_NAME));
             // write the email address
-            if (attr.containsKey(GpxData.META_AUTHOR_EMAIL)) {
-                String[] tmp = ((String)attr.get(GpxData.META_AUTHOR_EMAIL)).split("@");
+            if (attr.containsKey(META_AUTHOR_EMAIL)) {
+                String[] tmp = ((String)attr.get(META_AUTHOR_EMAIL)).split("@");
                 if (tmp.length == 2) {
                     inline("email", "id=\"" + tmp[0] + "\" domain=\""+tmp[1]+"\"");
@@ -107,17 +103,17 @@
             }
             // write the author link
-            gpxLink((GpxLink) attr.get(GpxData.META_AUTHOR_LINK));
+            gpxLink((GpxLink) attr.get(META_AUTHOR_LINK));
             closeln("author");
         }
 
         // write the copyright details
-        if (attr.containsKey(GpxData.META_COPYRIGHT_LICENSE)
-                || attr.containsKey(GpxData.META_COPYRIGHT_YEAR)) {
-            openAtt("copyright", "author=\""+ attr.get(GpxData.META_COPYRIGHT_AUTHOR) +"\"");
-            if (attr.containsKey(GpxData.META_COPYRIGHT_YEAR)) {
-                simpleTag("year", (String) attr.get(GpxData.META_COPYRIGHT_YEAR));
-            }
-            if (attr.containsKey(GpxData.META_COPYRIGHT_LICENSE)) {
-                simpleTag("license", encode((String) attr.get(GpxData.META_COPYRIGHT_LICENSE)));
+        if (attr.containsKey(META_COPYRIGHT_LICENSE)
+                || attr.containsKey(META_COPYRIGHT_YEAR)) {
+            openAtt("copyright", "author=\""+ attr.get(META_COPYRIGHT_AUTHOR) +"\"");
+            if (attr.containsKey(META_COPYRIGHT_YEAR)) {
+                simpleTag("year", (String) attr.get(META_COPYRIGHT_YEAR));
+            }
+            if (attr.containsKey(META_COPYRIGHT_LICENSE)) {
+                simpleTag("license", encode((String) attr.get(META_COPYRIGHT_LICENSE)));
             }
             closeln("copyright");
@@ -125,6 +121,6 @@
 
         // write links
-        if (attr.containsKey(GpxData.META_LINKS)) {
-            for (GpxLink link : (Collection<GpxLink>) attr.get(GpxData.META_LINKS)) {
+        if (attr.containsKey(META_LINKS)) {
+            for (GpxLink link : (Collection<GpxLink>) attr.get(META_LINKS)) {
                 gpxLink(link);
             }
@@ -132,6 +128,6 @@
 
         // write keywords
-        if (attr.containsKey(GpxData.META_KEYWORDS)) {
-            simpleTag("keywords", (String)attr.get(GpxData.META_KEYWORDS));
+        if (attr.containsKey(META_KEYWORDS)) {
+            simpleTag("keywords", (String)attr.get(META_KEYWORDS));
         }
 
