Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 10905)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 10906)
@@ -482,3 +482,46 @@
         return DataSource.getDataSourceBounds(dataSources);
     }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((dataSources == null) ? 0 : dataSources.hashCode());
+        result = prime * result + ((routes == null) ? 0 : routes.hashCode());
+        result = prime * result + ((tracks == null) ? 0 : tracks.hashCode());
+        result = prime * result + ((waypoints == null) ? 0 : waypoints.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        GpxData other = (GpxData) obj;
+        if (dataSources == null) {
+            if (other.dataSources != null)
+                return false;
+        } else if (!dataSources.equals(other.dataSources))
+            return false;
+        if (routes == null) {
+            if (other.routes != null)
+                return false;
+        } else if (!routes.equals(other.routes))
+            return false;
+        if (tracks == null) {
+            if (other.tracks != null)
+                return false;
+        } else if (!tracks.equals(other.tracks))
+            return false;
+        if (waypoints == null) {
+            if (other.waypoints != null)
+                return false;
+        } else if (!waypoints.equals(other.waypoints))
+            return false;
+        return true;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxRoute.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxRoute.java	(revision 10905)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxRoute.java	(revision 10906)
@@ -7,3 +7,25 @@
 public class GpxRoute extends WithAttributes {
     public Collection<WayPoint> routePoints = new LinkedList<>();
+
+    @Override
+    public int hashCode() {
+        return 31 * super.hashCode() + ((routePoints == null) ? 0 : routePoints.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        GpxRoute other = (GpxRoute) obj;
+        if (routePoints == null) {
+            if (other.routePoints != null)
+                return false;
+        } else if (!routePoints.equals(other.routePoints))
+            return false;
+        return true;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java	(revision 10905)
+++ trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java	(revision 10906)
@@ -17,5 +17,5 @@
 public class ImmutableGpxTrack extends WithAttributes implements GpxTrack {
 
-    private final Collection<GpxTrackSegment> segments;
+    private final List<GpxTrackSegment> segments;
     private final double length;
     private final Bounds bounds;
@@ -34,5 +34,5 @@
         }
         this.attr = Collections.unmodifiableMap(new HashMap<>(attributes));
-        this.segments = Collections.unmodifiableCollection(newSegments);
+        this.segments = Collections.unmodifiableList(newSegments);
         this.length = calculateLength();
         this.bounds = calculateBounds();
@@ -90,3 +90,25 @@
         return 0;
     }
+
+    @Override
+    public int hashCode() {
+        return 31 * super.hashCode() + ((segments == null) ? 0 : segments.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ImmutableGpxTrack other = (ImmutableGpxTrack) obj;
+        if (segments == null) {
+            if (other.segments != null)
+                return false;
+        } else if (!segments.equals(other.segments))
+            return false;
+        return true;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrackSegment.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrackSegment.java	(revision 10905)
+++ trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrackSegment.java	(revision 10906)
@@ -5,4 +5,5 @@
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 
 import org.openstreetmap.josm.data.Bounds;
@@ -10,10 +11,14 @@
 public class ImmutableGpxTrackSegment implements GpxTrackSegment {
 
-    private final Collection<WayPoint> wayPoints;
+    private final List<WayPoint> wayPoints;
     private final Bounds bounds;
     private final double length;
 
+    /**
+     * Constructs a new {@code ImmutableGpxTrackSegment}.
+     * @param wayPoints list of waypoints
+     */
     public ImmutableGpxTrackSegment(Collection<WayPoint> wayPoints) {
-        this.wayPoints = Collections.unmodifiableCollection(new ArrayList<>(wayPoints));
+        this.wayPoints = Collections.unmodifiableList(new ArrayList<>(wayPoints));
         this.bounds = calculateBounds();
         this.length = calculateLength();
@@ -70,3 +75,24 @@
     }
 
+    @Override
+    public int hashCode() {
+        return 31 + ((wayPoints == null) ? 0 : wayPoints.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ImmutableGpxTrackSegment other = (ImmutableGpxTrackSegment) obj;
+        if (wayPoints == null) {
+            if (other.wayPoints != null)
+                return false;
+        } else if (!wayPoints.equals(other.wayPoints))
+            return false;
+        return true;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 10905)
+++ trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 10906)
@@ -159,3 +159,34 @@
         return new ArrayList<>(attr.keySet());
     }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        long temp = Double.doubleToLongBits(lat);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        temp = Double.doubleToLongBits(lon);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        temp = Double.doubleToLongBits(time);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        WayPoint other = (WayPoint) obj;
+        if (Double.doubleToLongBits(lat) != Double.doubleToLongBits(other.lat))
+            return false;
+        if (Double.doubleToLongBits(lon) != Double.doubleToLongBits(other.lon))
+            return false;
+        if (Double.doubleToLongBits(time) != Double.doubleToLongBits(other.time))
+            return false;
+        return true;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java	(revision 10905)
+++ trunk/src/org/openstreetmap/josm/data/gpx/WithAttributes.java	(revision 10906)
@@ -90,3 +90,25 @@
         ext.put(key, value);
     }
+
+    @Override
+    public int hashCode() {
+        return 31 + ((attr == null) ? 0 : attr.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        WithAttributes other = (WithAttributes) obj;
+        if (attr == null) {
+            if (other.attr != null)
+                return false;
+        } else if (!attr.equals(other.attr))
+            return false;
+        return true;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/io/NmeaReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/NmeaReader.java	(revision 10905)
+++ trunk/src/org/openstreetmap/josm/io/NmeaReader.java	(revision 10906)
@@ -29,27 +29,4 @@
  */
 public class NmeaReader {
-
-    /** Handler for the different types that NMEA speaks. */
-    public enum NMEA_TYPE {
-
-        /** RMC = recommended minimum sentence C. */
-        GPRMC("$GPRMC"),
-        /** GPS positions. */
-        GPGGA("$GPGGA"),
-        /** SA = satellites active. */
-        GPGSA("$GPGSA"),
-        /** Course over ground and ground speed */
-        GPVTG("$GPVTG");
-
-        private final String type;
-
-        NMEA_TYPE(String type) {
-            this.type = type;
-        }
-
-        public String getType() {
-            return this.type;
-        }
-    }
 
     // GPVTG
