Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 15502)
@@ -73,5 +73,5 @@
      * A list of tracks this file consists of
      */
-    private final ArrayList<GpxTrack> privateTracks = new ArrayList<>();
+    private final ArrayList<IGpxTrack> privateTracks = new ArrayList<>();
     /**
      * GPX routes in this file
@@ -100,8 +100,8 @@
      * @see #getTracks()
      */
-    public final Collection<GpxTrack> tracks = new ListeningCollection<GpxTrack>(privateTracks, this::invalidate) {
+    public final Collection<IGpxTrack> tracks = new ListeningCollection<IGpxTrack>(privateTracks, this::invalidate) {
 
         @Override
-        protected void removed(GpxTrack cursor) {
+        protected void removed(IGpxTrack cursor) {
             cursor.removeListener(proxy);
             super.removed(cursor);
@@ -109,5 +109,5 @@
 
         @Override
-        protected void added(GpxTrack cursor) {
+        protected void added(IGpxTrack cursor) {
             super.added(cursor);
             cursor.addListener(proxy);
@@ -174,5 +174,5 @@
 
         if (cutOverlapping) {
-            for (GpxTrack trk : other.privateTracks) {
+            for (IGpxTrack trk : other.privateTracks) {
                 cutOverlapping(trk, connect);
             }
@@ -186,5 +186,5 @@
     }
 
-    private void cutOverlapping(GpxTrack trk, boolean connect) {
+    private void cutOverlapping(IGpxTrack trk, boolean connect) {
         List<IGpxTrackSegment> segsOld = new ArrayList<>(trk.getSegments());
         List<IGpxTrackSegment> segsNew = new ArrayList<>();
@@ -366,5 +366,5 @@
         if (segSpans == null) {
             segSpans = new ArrayList<>();
-            for (GpxTrack trk : privateTracks) {
+            for (IGpxTrack trk : privateTracks) {
                 for (IGpxTrackSegment seg : trk.getSegments()) {
                     GpxTrackSegmentSpan s = GpxTrackSegmentSpan.tryGetFromSegment(seg);
@@ -392,5 +392,5 @@
      * @return The tracks.
      */
-    public synchronized Collection<GpxTrack> getTracks() {
+    public synchronized Collection<IGpxTrack> getTracks() {
         return Collections.unmodifiableCollection(privateTracks);
     }
@@ -418,5 +418,5 @@
      * @since 12156
      */
-    public synchronized void addTrack(GpxTrack track) {
+    public synchronized void addTrack(IGpxTrack track) {
         if (privateTracks.stream().anyMatch(t -> t == track)) {
             throw new IllegalArgumentException(MessageFormat.format("The track was already added to this data: {0}", track));
@@ -432,5 +432,5 @@
      * @since 12156
      */
-    public synchronized void removeTrack(GpxTrack track) {
+    public synchronized void removeTrack(IGpxTrack track) {
         if (!privateTracks.removeIf(t -> t == track)) {
             throw new IllegalArgumentException(MessageFormat.format("The track was not in this data: {0}", track));
@@ -626,5 +626,5 @@
      * @return The stream
      * @see #getTracks()
-     * @see GpxTrack#getSegments()
+     * @see IGpxTrack#getSegments()
      * @see IGpxTrackSegment#getWayPoints()
      * @since 12156
@@ -698,5 +698,5 @@
             }
         }
-        for (GpxTrack trk : privateTracks) {
+        for (IGpxTrack trk : privateTracks) {
             Bounds trkBounds = trk.getBounds();
             if (trkBounds != null) {
@@ -716,5 +716,5 @@
      */
     public synchronized double length() {
-        return privateTracks.stream().mapToDouble(GpxTrack::length).sum();
+        return privateTracks.stream().mapToDouble(IGpxTrack::length).sum();
     }
 
@@ -724,5 +724,5 @@
      * @return  minimum and maximum dates in array of 2 elements
      */
-    public static Date[] getMinMaxTimeForTrack(GpxTrack trk) {
+    public static Date[] getMinMaxTimeForTrack(IGpxTrack trk) {
         final LongSummaryStatistics statistics = trk.getSegments().stream()
                 .flatMap(seg -> seg.getWayPoints().stream())
@@ -793,5 +793,5 @@
         double py = p.north();
         double rx = 0.0, ry = 0.0, sx, sy, x, y;
-        for (GpxTrack track : privateTracks) {
+        for (IGpxTrack track : privateTracks) {
             for (IGpxTrackSegment seg : track.getSegments()) {
                 WayPoint r = null;
@@ -907,5 +907,5 @@
     public static class LinesIterator implements Iterator<Line> {
 
-        private Iterator<GpxTrack> itTracks;
+        private Iterator<IGpxTrack> itTracks;
         private int idxTracks;
         private Iterator<IGpxTrackSegment> itTrackSegments;
@@ -915,5 +915,5 @@
         private final boolean[] trackVisibility;
         private Map<String, Object> trackAttributes;
-        private GpxTrack curTrack;
+        private IGpxTrack curTrack;
 
         /**
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelation.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelation.java	(revision 15502)
@@ -38,5 +38,5 @@
         List<List<List<WayPoint>>> trks = new ArrayList<>();
 
-        for (GpxTrack trk : selectedGpx.tracks) {
+        for (IGpxTrack trk : selectedGpx.tracks) {
             List<List<WayPoint>> segs = new ArrayList<>();
             for (IGpxTrackSegment seg : trk.getSegments()) {
Index: trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 15502)
@@ -32,5 +32,5 @@
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeListener;
-import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.IGpxTrack;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.data.projection.Projection;
@@ -126,5 +126,5 @@
     public void setColor(Color color) {
         data.beginUpdate();
-        for (GpxTrack trk : data.getTracks()) {
+        for (IGpxTrack trk : data.getTracks()) {
             trk.setColor(color);
         }
@@ -143,5 +143,5 @@
      * @return The timespan as a string
      */
-    public static String getTimespanForTrack(GpxTrack trk) {
+    public static String getTimespanForTrack(IGpxTrack trk) {
         Date[] bounds = GpxData.getMinMaxTimeForTrack(trk);
         String ts = "";
@@ -201,5 +201,5 @@
                 .append("</td></tr></thead>");
 
-            for (GpxTrack trk : data.getTracks()) {
+            for (IGpxTrack trk : data.getTracks()) {
                 info.append("<tr><td>");
                 if (trk.getAttributes().containsKey(GpxConstants.GPX_NAME)) {
@@ -330,5 +330,5 @@
         long from = fromDate.getTime();
         long to = toDate.getTime();
-        for (GpxTrack trk : data.getTracks()) {
+        for (IGpxTrack trk : data.getTracks()) {
             Date[] t = GpxData.getMinMaxTimeForTrack(trk);
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 15502)
@@ -72,5 +72,5 @@
 import org.openstreetmap.josm.data.gpx.GpxTimeOffset;
 import org.openstreetmap.josm.data.gpx.GpxTimezone;
-import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.IGpxTrack;
 import org.openstreetmap.josm.data.gpx.IGpxTrackSegment;
 import org.openstreetmap.josm.data.gpx.WayPoint;
@@ -1263,5 +1263,5 @@
         long firstGPXDate = -1;
         // Finds first GPX point
-        outer: for (GpxTrack trk : gpx.tracks) {
+        outer: for (IGpxTrack trk : gpx.tracks) {
             for (IGpxTrackSegment segment : trk.getSegments()) {
                 for (WayPoint curWp : segment.getWayPoints()) {
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 15502)
@@ -35,4 +35,5 @@
 import javax.swing.table.DefaultTableModel;
 import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableModel;
 import javax.swing.table.TableRowSorter;
 
@@ -40,5 +41,5 @@
 import org.openstreetmap.josm.data.SystemOfMeasurement;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
-import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.IGpxTrack;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.MainApplication;
@@ -119,5 +120,5 @@
         Object[][] tracks = new Object[layer.data.tracks.size()][5];
         int i = 0;
-        for (GpxTrack trk : layer.data.tracks) {
+        for (IGpxTrack trk : layer.data.tracks) {
             Map<String, Object> attr = trk.getAttributes();
             String name = (String) Optional.ofNullable(attr.get(GpxConstants.GPX_NAME)).orElse("");
@@ -132,7 +133,7 @@
     }
 
-    private void showColorDialog(List<GpxTrack> tracks) {
+    private void showColorDialog(List<IGpxTrack> tracks) {
         Color cl = tracks.stream().filter(Objects::nonNull)
-                .map(GpxTrack::getColor).filter(Objects::nonNull)
+                .map(IGpxTrack::getColor).filter(Objects::nonNull)
                 .findAny().orElse(GpxDrawHelper.DEFAULT_COLOR_PROPERTY.get());
         JColorChooser c = new JColorChooser(cl);
@@ -171,75 +172,5 @@
         final String[] headers = {tr("Name"), tr("Description"), tr("Timespan"), tr("Length"), tr("URL")};
         DefaultTableModel model = new DefaultTableModel(content, headers);
-        final JTable t = new JTable(model) {
-            @Override
-            public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
-                Component c = super.prepareRenderer(renderer, row, col);
-                if (c instanceof JComponent) {
-                    JComponent jc = (JComponent) c;
-                    jc.setToolTipText(getValueAt(row, col).toString());
-                    if (content.length > row
-                            && content[row].length > 5
-                            && content[row][5] instanceof GpxTrack) {
-                        Color color = ((GpxTrack) content[row][5]).getColor();
-                        if (color != null) {
-                            double brightness = Math.sqrt(Math.pow(color.getRed(), 2) * .241
-                                    + Math.pow(color.getGreen(), 2) * .691
-                                    + Math.pow(color.getBlue(), 2) * .068);
-                            if (brightness > 250) {
-                                color = color.darker();
-                            }
-                            if (isRowSelected(row)) {
-                                jc.setBackground(color);
-                                if (brightness <= 130) {
-                                    jc.setForeground(Color.WHITE);
-                                } else {
-                                    jc.setForeground(Color.BLACK);
-                                }
-                            } else {
-                                if (brightness > 200) {
-                                    color = color.darker(); //brightness >250 is darkened twice on purpose
-                                }
-                                jc.setForeground(color);
-                                jc.setBackground(Color.WHITE);
-                            }
-                        } else {
-                            jc.setForeground(Color.BLACK);
-                            if (isRowSelected(row)) {
-                                jc.setBackground(new Color(175, 210, 210));
-                            } else {
-                                jc.setBackground(Color.WHITE);
-                            }
-                        }
-                    }
-                }
-                return c;
-            }
-
-            @Override
-            public boolean isCellEditable(int rowIndex, int colIndex) {
-                return colIndex <= 1;
-            }
-
-            @Override
-            public void tableChanged(TableModelEvent e) {
-                super.tableChanged(e);
-                int col = e.getColumn();
-                int row = e.getFirstRow();
-                if (row >= 0 && row < content.length && col >= 0 && col <= 1) {
-                    Object t = content[row][5];
-                    String val = (String) getValueAt(row, col);
-                    if (t != null && t instanceof GpxTrack) {
-                        GpxTrack trk = (GpxTrack) t;
-                        if (col == 0) {
-                            trk.put("name", val);
-                        } else {
-                            trk.put("desc", val);
-                        }
-                    } else {
-                        throw new InvalidArgumentException("Invalid object in table, must be GpxTrack.");
-                    }
-                }
-            }
-        };
+        final GpxTrackTable t = new GpxTrackTable(content, model);
         // define how to sort row
         TableRowSorter<DefaultTableModel> rowSorter = new TableRowSorter<>();
@@ -366,9 +297,9 @@
             protected void buttonAction(int buttonIndex, ActionEvent evt) {
                 if (buttonIndex == 0) {
-                    List<GpxTrack> trks = new ArrayList<>();
+                    List<IGpxTrack> trks = new ArrayList<>();
                     for (int i : table.getSelectedRows()) {
                         Object trk = content[i][5];
-                        if (trk != null && trk instanceof GpxTrack) {
-                            trks.add((GpxTrack) trk);
+                        if (trk != null && trk instanceof IGpxTrack) {
+                            trks.add((IGpxTrack) trk);
                         }
                     }
@@ -407,3 +338,82 @@
         layer.setVisible(v == 2 || !s.isSelectionEmpty());
     }
+
+    private static class GpxTrackTable extends JTable {
+        final Object[][] content;
+
+        public GpxTrackTable(Object[][] content, TableModel model) {
+            super(model);
+            this.content = content;
+        }
+
+        @Override
+        public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
+            Component c = super.prepareRenderer(renderer, row, col);
+            if (c instanceof JComponent) {
+                JComponent jc = (JComponent) c;
+                jc.setToolTipText(getValueAt(row, col).toString());
+                if (content.length > row
+                        && content[row].length > 5
+                        && content[row][5] instanceof IGpxTrack) {
+                    Color color = ((IGpxTrack) content[row][5]).getColor();
+                    if (color != null) {
+                        double brightness = Math.sqrt(Math.pow(color.getRed(), 2) * .241
+                                + Math.pow(color.getGreen(), 2) * .691
+                                + Math.pow(color.getBlue(), 2) * .068);
+                        if (brightness > 250) {
+                            color = color.darker();
+                        }
+                        if (isRowSelected(row)) {
+                            jc.setBackground(color);
+                            if (brightness <= 130) {
+                                jc.setForeground(Color.WHITE);
+                            } else {
+                                jc.setForeground(Color.BLACK);
+                            }
+                        } else {
+                            if (brightness > 200) {
+                                color = color.darker(); //brightness >250 is darkened twice on purpose
+                            }
+                            jc.setForeground(color);
+                            jc.setBackground(Color.WHITE);
+                        }
+                    } else {
+                        jc.setForeground(Color.BLACK);
+                        if (isRowSelected(row)) {
+                            jc.setBackground(new Color(175, 210, 210));
+                        } else {
+                            jc.setBackground(Color.WHITE);
+                        }
+                    }
+                }
+            }
+            return c;
+        }
+
+        @Override
+        public boolean isCellEditable(int rowIndex, int colIndex) {
+            return colIndex <= 1;
+        }
+
+        @Override
+        public void tableChanged(TableModelEvent e) {
+            super.tableChanged(e);
+            int col = e.getColumn();
+            int row = e.getFirstRow();
+            if (row >= 0 && row < content.length && col >= 0 && col <= 1) {
+                Object t = content[row][5];
+                String val = (String) getValueAt(row, col);
+                if (t != null && t instanceof IGpxTrack) {
+                    IGpxTrack trk = (IGpxTrack) t;
+                    if (col == 0) {
+                        trk.put("name", val);
+                    } else {
+                        trk.put("desc", val);
+                    }
+                } else {
+                    throw new InvalidArgumentException("Invalid object in table, must be IGpxTrack.");
+                }
+            }
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java	(revision 15502)
@@ -8,5 +8,5 @@
 import org.openstreetmap.josm.actions.DownloadAlongAction;
 import org.openstreetmap.josm.data.gpx.GpxData;
-import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.IGpxTrack;
 import org.openstreetmap.josm.data.gpx.IGpxTrackSegment;
 import org.openstreetmap.josm.data.gpx.WayPoint;
@@ -60,5 +60,5 @@
         Path2D gpxPath = new Path2D.Double();
         if (near == NEAR_TRACK || near == NEAR_BOTH) {
-            for (GpxTrack trk : data.tracks) {
+            for (IGpxTrack trk : data.tracks) {
                 for (IGpxTrackSegment segment : trk.getSegments()) {
                     boolean first = true;
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java	(revision 15502)
@@ -16,5 +16,5 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.gpx.GpxData;
-import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.IGpxTrack;
 import org.openstreetmap.josm.data.gpx.IGpxTrackSegment;
 import org.openstreetmap.josm.data.gpx.WayPoint;
@@ -92,5 +92,5 @@
     PrecacheWmsTask createTask() {
         List<LatLon> points = new ArrayList<>();
-        for (GpxTrack trk : data.tracks) {
+        for (IGpxTrack trk : data.tracks) {
             for (IGpxTrackSegment segment : trk.getSegments()) {
                 for (WayPoint p : segment.getWayPoints()) {
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/ImportAudioAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/ImportAudioAction.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/ImportAudioAction.java	(revision 15502)
@@ -21,5 +21,5 @@
 import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
-import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.IGpxTrack;
 import org.openstreetmap.josm.data.gpx.IGpxTrackSegment;
 import org.openstreetmap.josm.data.gpx.WayPoint;
@@ -147,5 +147,5 @@
         double firstTime = -1.0;
         if (hasTracks) {
-            for (GpxTrack track : layer.data.tracks) {
+            for (IGpxTrack track : layer.data.tracks) {
                 for (IGpxTrackSegment seg : track.getSegments()) {
                     for (WayPoint w : seg.getWayPoints()) {
@@ -206,5 +206,5 @@
         if (layer.data.tracks != null && Config.getPref().getBoolean("marker.audiofromnamedtrackpoints", false)
                 && !layer.data.tracks.isEmpty()) {
-            for (GpxTrack track : layer.data.tracks) {
+            for (IGpxTrack track : layer.data.tracks) {
                 for (IGpxTrackSegment seg : track.getSegments()) {
                     for (WayPoint w : seg.getWayPoints()) {
@@ -227,5 +227,5 @@
             WayPoint w2 = null;
 
-            for (GpxTrack track : layer.data.tracks) {
+            for (IGpxTrack track : layer.data.tracks) {
                 for (IGpxTrackSegment seg : track.getSegments()) {
                     for (WayPoint w : seg.getWayPoints()) {
@@ -263,5 +263,5 @@
         if ((Config.getPref().getBoolean("marker.audiofromstart") || waypoints.isEmpty()) && hasTracks) {
             boolean gotOne = false;
-            for (GpxTrack track : layer.data.tracks) {
+            for (IGpxTrack track : layer.data.tracks) {
                 for (IGpxTrackSegment seg : track.getSegments()) {
                     for (WayPoint w : seg.getWayPoints()) {
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java	(revision 15502)
@@ -18,5 +18,5 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.IGpxTrack;
 import org.openstreetmap.josm.data.gpx.IGpxTrackSegment;
 import org.openstreetmap.josm.data.gpx.WayPoint;
@@ -327,5 +327,5 @@
         WayPoint w2 = null;
 
-        for (GpxTrack track : trackLayer.data.getTracks()) {
+        for (IGpxTrack track : trackLayer.data.getTracks()) {
             for (IGpxTrackSegment trackseg : track.getSegments()) {
                 for (WayPoint w: trackseg.getWayPoints()) {
Index: trunk/src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 15501)
+++ trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 15502)
@@ -29,4 +29,5 @@
 import org.openstreetmap.josm.data.gpx.GpxRoute;
 import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.IGpxTrack;
 import org.openstreetmap.josm.data.gpx.IGpxTrackSegment;
 import org.openstreetmap.josm.data.gpx.IWithAttributes;
@@ -85,5 +86,7 @@
         //Prepare extensions for writing
         data.beginUpdate();
-        data.getTracks().forEach(trk -> trk.convertColor(colorFormat));
+        data.getTracks().stream()
+        .filter(GpxTrack.class::isInstance).map(GpxTrack.class::cast)
+        .forEach(trk -> trk.convertColor(colorFormat));
         data.getExtensions().removeAllWithPrefix("josm");
         if (data.fromServer) {
@@ -259,5 +262,5 @@
 
     private void writeTracks() {
-        for (GpxTrack trk : data.getTracks()) {
+        for (IGpxTrack trk : data.getTracks()) {
             openln("trk");
             writeAttr(trk, RTE_TRK_KEYS);
