Index: /trunk/src/org/openstreetmap/josm/data/gpx/GpxTrack.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/gpx/GpxTrack.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/data/gpx/GpxTrack.java	(revision 9949)
@@ -9,18 +9,34 @@
 /**
  * Read-only gpx track. Implementations doesn't have to be immutable, but should always be thread safe.
- *
+ * @since 444
  */
 public interface GpxTrack extends IWithAttributes {
 
+    /**
+     * Returns the track segments.
+     * @return the track segments
+     */
     Collection<GpxTrackSegment> getSegments();
 
+    /**
+     * Returns the track attributes.
+     * @return the track attributes
+     */
     Map<String, Object> getAttributes();
 
+    /**
+     * Returns the track bounds.
+     * @return the track bounds
+     */
     Bounds getBounds();
 
+    /**
+     * Returns the track length.
+     * @return the track length
+     */
     double length();
 
     /**
-     *
+     * Returns the number of times this track has been changed.
      * @return Number of times this track has been changed. Always 0 for read-only tracks
      */
Index: /trunk/src/org/openstreetmap/josm/data/gpx/GpxTrackSegment.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/gpx/GpxTrackSegment.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/data/gpx/GpxTrackSegment.java	(revision 9949)
@@ -8,16 +8,28 @@
 /**
  * Read-only gpx track segments. Implementations doesn't have to be immutable, but should always be thread safe.
- *
+ * @since 2907
  */
 public interface GpxTrackSegment {
 
+    /**
+     * Returns the segment bounds.
+     * @return the segment bounds
+     */
     Bounds getBounds();
 
+    /**
+     * Returns the segment waypoints.
+     * @return the segment waypoints
+     */
     Collection<WayPoint> getWayPoints();
 
+    /**
+     * Returns the segment length.
+     * @return the segment length
+     */
     double length();
 
     /**
-     *
+     * Returns the number of times this track has been changed
      * @return Number of times this track has been changed. Always 0 for read-only segments
      */
Index: /trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/data/gpx/ImmutableGpxTrack.java	(revision 9949)
@@ -11,4 +11,8 @@
 import org.openstreetmap.josm.data.Bounds;
 
+/**
+ * Immutable GPX track.
+ * @since 2907
+ */
 public class ImmutableGpxTrack extends WithAttributes implements GpxTrack {
 
@@ -17,4 +21,9 @@
     private final Bounds bounds;
 
+    /**
+     * Constructs a new {@code ImmutableGpxTrack}.
+     * @param trackSegs track segments
+     * @param attributes track attributes
+     */
     public ImmutableGpxTrack(Collection<Collection<WayPoint>> trackSegs, Map<String, Object> attributes) {
         List<GpxTrackSegment> newSegments = new ArrayList<>();
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java	(revision 9949)
@@ -67,4 +67,8 @@
     }
 
+    /**
+     * Constructs a new {@code LayerListPopup}.
+     * @param selectedLayers list of selected layers
+     */
     public LayerListPopup(List<Layer> selectedLayers) {
 
Index: /trunk/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java	(revision 9949)
@@ -23,20 +23,23 @@
 
 public class CustomizeColor extends AbstractAction implements LayerAction, MultiLayerAction {
-    private transient List<Layer> layers;
+    private final transient List<Layer> layers;
 
+    /**
+     * Constructs a new {@code CustomizeColor} for a given list of layers.
+     * @param l list of layers
+     */
     public CustomizeColor(List<Layer> l) {
-        this();
+        super(tr("Customize Color"), ImageProvider.get("colorchooser"));
+        putValue("help", ht("/Action/LayerCustomizeColor"));
         layers = l;
     }
 
+    /**
+     * Constructs a new {@code CustomizeColor} for a single layer.
+     * @param l layer
+     */
     public CustomizeColor(Layer l) {
-        this();
-        layers = new LinkedList<>();
+        this(new LinkedList<Layer>());
         layers.add(l);
-    }
-
-    private CustomizeColor() {
-        super(tr("Customize Color"), ImageProvider.get("colorchooser"));
-        putValue("help", ht("/Action/LayerCustomizeColor"));
     }
 
@@ -63,5 +66,6 @@
     public void actionPerformed(ActionEvent e) {
         Color cl = layers.get(0).getColor(false);
-        if (cl == null) cl = Color.gray;
+        if (cl == null)
+            cl = Color.gray;
         JColorChooser c = new JColorChooser(cl);
         Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
Index: /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 9949)
@@ -52,6 +52,7 @@
 public class GpxLayer extends Layer {
 
+    /** GPX data */
     public GpxData data;
-    private boolean isLocalFile;
+    private final boolean isLocalFile;
     // used by ChooseTrackVisibilityAction to determine which tracks to show/hide
     public boolean[] trackVisibility = new boolean[0];
@@ -62,20 +63,34 @@
     private final GpxDrawHelper drawHelper;
 
+    /**
+     * Constructs a new {@code GpxLayer} without name.
+     * @param d GPX data
+     */
     public GpxLayer(GpxData d) {
+        this(d, null, false);
+    }
+
+    /**
+     * Constructs a new {@code GpxLayer} with a given name.
+     * @param d GPX data
+     * @param name layer name
+     */
+    public GpxLayer(GpxData d, String name) {
+        this(d, name, false);
+    }
+
+    /**
+     * Constructs a new {@code GpxLayer} with a given name, thah can be attached to a local file.
+     * @param d GPX data
+     * @param name layer name
+     * @param isLocal whether data is attached to a local file
+     */
+    public GpxLayer(GpxData d, String name, boolean isLocal) {
         super(d.getString(GpxConstants.META_NAME));
         data = d;
         drawHelper = new GpxDrawHelper(data);
         ensureTrackVisibilityLength();
-    }
-
-    public GpxLayer(GpxData d, String name) {
-        this(d);
-        this.setName(name);
-    }
-
-    public GpxLayer(GpxData d, String name, boolean isLocal) {
-        this(d);
-        this.setName(name);
-        this.isLocalFile = isLocal;
+        setName(name);
+        isLocalFile = isLocal;
     }
 
@@ -204,4 +219,8 @@
     }
 
+    /**
+     * Determines if data is attached to a local file.
+     * @return {@code true} if data is attached to a local file, {@code false} otherwise
+     */
     public boolean isLocalFile() {
         return isLocalFile;
Index: /trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java	(revision 9949)
@@ -52,4 +52,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -91,5 +92,5 @@
         if (info.getIcon() != null) {
             icon = new ImageProvider(info.getIcon()).setOptional(true).
-                    setMaxHeight(ICON_SIZE).setMaxWidth(ICON_SIZE).get();
+                    setMaxSize(ImageSizes.LAYER).get();
         }
         if (icon == null) {
Index: /trunk/src/org/openstreetmap/josm/gui/layer/Layer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 9949)
@@ -50,11 +50,33 @@
 public abstract class Layer implements Destroyable, MapViewPaintable, ProjectionChangeListener {
 
+    /**
+     * Action related to a single layer.
+     */
     public interface LayerAction {
+
+        /**
+         * Determines if this action supports a given list of layers.
+         * @param layers list of layers
+         * @return {@code true} if this action supports the given list of layers, {@code false} otherwise
+         */
         boolean supportLayers(List<Layer> layers);
 
+        /**
+         * Creates and return the menu component.
+         * @return the menu component
+         */
         Component createMenuComponent();
     }
 
+    /**
+     * Action related to several layers.
+     */
     public interface MultiLayerAction {
+
+        /**
+         * Returns the action for a given list of layers.
+         * @param layers list of layers
+         * @return the action for the given list of layers
+         */
         Action getMultiLayerAction(List<Layer> layers);
     }
@@ -64,4 +86,5 @@
      */
     public static class SeparatorLayerAction extends AbstractAction implements LayerAction {
+        /** Unique instance */
         public static final SeparatorLayerAction INSTANCE = new SeparatorLayerAction();
 
@@ -86,6 +109,4 @@
     public static final String NAME_PROP = Layer.class.getName() + ".name";
     public static final String FILTER_STATE_PROP = Layer.class.getName() + ".filterstate";
-
-    public static final int ICON_SIZE = 16;
 
     /**
Index: /trunk/src/org/openstreetmap/josm/tools/HttpClient.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/HttpClient.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/tools/HttpClient.java	(revision 9949)
@@ -11,5 +11,4 @@
 import java.net.CookieHandler;
 import java.net.CookieManager;
-import java.net.HttpRetryException;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -522,26 +521,4 @@
 
     /**
-     * This method is used to enable streaming of a HTTP request body without internal buffering,
-     * when the content length is known in advance.
-     * <p>
-     * An exception will be thrown if the application attempts to write more data than the indicated content-length,
-     * or if the application closes the OutputStream before writing the indicated amount.
-     * <p>
-     * When output streaming is enabled, authentication and redirection cannot be handled automatically.
-     * A {@linkplain HttpRetryException} will be thrown when reading the response if authentication or redirection
-     * are required. This exception can be queried for the details of the error.
-     *
-     * @param contentLength The number of bytes which will be written to the OutputStream
-     * @return {@code this}
-     * @see HttpURLConnection#setFixedLengthStreamingMode(long)
-     * @since 9178
-     * @deprecated Submitting data via POST, PUT, DELETE automatically sets this property on the connection
-     */
-    @Deprecated
-    public HttpClient setFixedLengthStreamingMode(long contentLength) {
-        return this;
-    }
-
-    /**
      * Sets the {@code Accept} header.
      * @param accept header value
Index: /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 9948)
+++ /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 9949)
@@ -132,7 +132,7 @@
      */
     public enum ImageSizes {
-        /** SMALL_ICON value of on Action */
+        /** SMALL_ICON value of an Action */
         SMALLICON(Main.pref.getInteger("iconsize.smallicon", 16)),
-        /** LARGE_ICON_KEY value of on Action */
+        /** LARGE_ICON_KEY value of an Action */
         LARGEICON(Main.pref.getInteger("iconsize.largeicon", 24)),
         /** map icon */
@@ -375,16 +375,4 @@
         overlayInfo.add(overlay);
         return this;
-    }
-
-    /**
-     * Convert enumerated size values to real numbers
-     * @param size the size enumeration
-     * @return dimension of image in pixels
-     * @since 7687
-     * @deprecated Use {@link ImageSizes#getImageDimension()} instead
-     */
-    @Deprecated
-    public static Dimension getImageSizes(ImageSizes size) {
-        return (size == null ? ImageSizes.DEFAULT : size).getImageDimension();
     }
 
Index: /trunk/test/unit/org/openstreetmap/josm/gui/layer/GpxLayerTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/layer/GpxLayerTest.java	(revision 9949)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/layer/GpxLayerTest.java	(revision 9949)
@@ -0,0 +1,205 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.layer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+
+import javax.swing.JScrollPane;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openstreetmap.josm.JOSMFixture;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.TestUtils;
+import org.openstreetmap.josm.data.gpx.GpxData;
+import org.openstreetmap.josm.data.gpx.ImmutableGpxTrack;
+import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.data.projection.Projections;
+import org.openstreetmap.josm.gui.widgets.HtmlPanel;
+import org.openstreetmap.josm.io.GpxReaderTest;
+import org.xml.sax.SAXException;
+
+/**
+ * Unit tests of {@link GpxLayer} class.
+ */
+public class GpxLayerTest {
+
+    /**
+     * Setup tests
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() {
+        JOSMFixture.createUnitTestFixture().init(true);
+    }
+
+    private static String getHtml(GpxLayer layer) {
+        return ((HtmlPanel) ((JScrollPane) layer.getInfoComponent()).getViewport().getView()).getEditorPane().getText();
+    }
+
+    /**
+     * Returns minimal GPX data.
+     * @return minimal GPX data, with a single waypoint, a single track composed of a single segment
+     * @throws IOException if any I/O error occurs
+     * @throws SAXException if any SAX error occurs
+     */
+    public static GpxData getMinimalGpxData() throws IOException, SAXException {
+        return GpxReaderTest.parseGpxData(TestUtils.getTestDataRoot() + "minimal.gpx");
+    }
+
+    /**
+     * Returns minimal GPX layer.
+     * @return minimal GPX layer, with a single waypoint, a single track composed of a single segment
+     * @throws IOException if any I/O error occurs
+     * @throws SAXException if any SAX error occurs
+     */
+    public static GpxLayer getMinimalGpxLayer() throws IOException, SAXException {
+        return new GpxLayer(getMinimalGpxData());
+    }
+
+    /**
+     * Unit test of {@link GpxLayer#GpxLayer}.
+     * @throws Exception if any error occurs
+     */
+    @Test
+    public void testGpxLayer() throws Exception {
+        GpxLayer layer = new GpxLayer(new GpxData(), "foo", false);
+        assertEquals("foo", layer.getName());
+        assertFalse(layer.isLocalFile());
+        assertEquals(Color.MAGENTA, layer.getColor(false));
+        assertEquals("<html>0 tracks, 0 routes, 0 waypoints<br>Length: < 0.01 m<br></html>", layer.getToolTipText());
+
+        GpxLayer layer2 = new GpxLayer(new GpxData(), "bar", true);
+        assertEquals("bar", layer2.getName());
+        assertTrue(layer2.isLocalFile());
+        assertEquals(Color.MAGENTA, layer2.getColor(true));
+        assertEquals("<html>0 tracks, 0 routes, 0 waypoints<br>Length: < 0.01 m<br></html>", layer2.getToolTipText());
+
+        assertFalse(layer.isChanged());
+        assertTrue(layer.checkSaveConditions());
+        assertTrue(layer.isInfoResizable());
+        assertTrue(layer.isSavable());
+        assertTrue(layer.isMergable(layer2));
+
+        layer.projectionChanged(null, null);
+        layer.projectionChanged(null, Projections.getProjectionByCode("EPSG:3857"));
+    }
+
+    /**
+     * Unit test of {@link GpxLayer#getInfoComponent}.
+     * @throws Exception if any error occurs
+     */
+    @Test
+    public void testGetInfoComponent() throws Exception {
+        assertEquals("<html>\n"+
+                     "  <head>\n" +
+                     "    \n" +
+                     "  </head>\n" +
+                     "  <body>\n" +
+                     "    Length: 0.01 m<br>0 routes, 0 waypoints<br>\n" +
+                     "  </body>\n" +
+                     "</html>\n",
+                     getHtml(new GpxLayer(new GpxData())));
+
+        assertEquals("<html>\n"+
+                     "  <head>\n" +
+                     "    \n" +
+                     "  </head>\n" +
+                     "  <body>\n" +
+                     "    <table>\n" +
+                     "      <tr align=\"center\">\n" +
+                     "        <td colspan=\"5\">\n" +
+                     "          1 track\n" +
+                     "        </td>\n" +
+                     "      </tr>\n" +
+                     "      <tr align=\"center\">\n" +
+                     "        <td>\n" +
+                     "          Name\n" +
+                     "        </td>\n" +
+                     "        <td>\n" +
+                     "          Description\n" +
+                     "        </td>\n" +
+                     "        <td>\n" +
+                     "          Timespan\n" +
+                     "        </td>\n" +
+                     "        <td>\n" +
+                     "          Length\n" +
+                     "        </td>\n" +
+                     "        <td>\n" +
+                     "          URL\n" +
+                     "        </td>\n" +
+                     "      </tr>\n" +
+                     "      <tr>\n" +
+                     "        <td>\n" +
+                     "          2016-01-03 20:40:14\n" +
+                     "        </td>\n" +
+                     "        <td>\n" +
+                     "          \n" +
+                     "        </td>\n" +
+                     "        <td>\n" +
+                     "          1/3/16 12:59 PM - 1:00 PM (0:00)\n" +
+                     "        </td>\n" +
+                     "        <td>\n" +
+                     "          12.0 m\n" +
+                     "        </td>\n" +
+                     "        <td>\n" +
+                     "          \n" +
+                     "        </td>\n" +
+                     "      </tr>\n" +
+                     "    </table>\n" +
+                     "    <br>\n" +
+                     "    <br>\n" +
+                     "    Length: 12.0 m<br>0 routes, 1 waypoint<br>\n" +
+                     "  </body>\n" +
+                     "</html>\n",
+                     getHtml(getMinimalGpxLayer()));
+    }
+
+    /**
+     * Unit test of {@link GpxLayer#getTimespanForTrack}.
+     * @throws Exception if any error occurs
+     */
+    @Test
+    public void testGetTimespanForTrack() throws Exception {
+        assertEquals("", GpxLayer.getTimespanForTrack(
+                new ImmutableGpxTrack(new ArrayList<Collection<WayPoint>>(), new HashMap<String, Object>())));
+
+        assertEquals("1/3/16 12:59 PM - 1:00 PM (0:00)", GpxLayer.getTimespanForTrack(getMinimalGpxData().tracks.iterator().next()));
+    }
+
+    /**
+     * Unit test of {@link GpxLayer#mergeFrom}.
+     * @throws Exception if any error occurs
+     */
+    @Test
+    public void testMergeFrom() throws Exception {
+        GpxLayer layer = new GpxLayer(new GpxData());
+        assertTrue(layer.data.isEmpty());
+        layer.mergeFrom(getMinimalGpxLayer());
+        assertFalse(layer.data.isEmpty());
+        assertEquals(1, layer.data.tracks.size());
+        assertEquals(1, layer.data.waypoints.size());
+    }
+
+    /**
+     * Unit test of {@link GpxLayer#paint}.
+     * @throws Exception if any error occurs
+     */
+    @Test
+    public void testPaint() throws Exception {
+        GpxLayer layer = getMinimalGpxLayer();
+        try {
+            Main.main.addLayer(layer);
+            assertTrue(layer.getMenuEntries().length > 0);
+            layer.paint(TestUtils.newGraphics(), Main.map.mapView, layer.data.getMetaBounds());
+        } finally {
+            Main.main.removeLayer(layer);
+        }
+    }
+}
Index: /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityActionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityActionTest.java	(revision 9948)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityActionTest.java	(revision 9949)
@@ -5,8 +5,5 @@
 import org.junit.Test;
 import org.openstreetmap.josm.JOSMFixture;
-import org.openstreetmap.josm.TestUtils;
-import org.openstreetmap.josm.data.gpx.GpxData;
-import org.openstreetmap.josm.gui.layer.GpxLayer;
-import org.openstreetmap.josm.io.GpxReaderTest;
+import org.openstreetmap.josm.gui.layer.GpxLayerTest;
 
 /**
@@ -29,8 +26,5 @@
     @Test
     public void testAction() throws Exception {
-        final GpxData gpx = GpxReaderTest.parseGpxData(TestUtils.getTestDataRoot() + "minimal.gpx");
-        GpxLayer gpxLayer = new GpxLayer(gpx);
-        ChooseTrackVisibilityAction action = new ChooseTrackVisibilityAction(gpxLayer);
-        action.actionPerformed(null);
+        new ChooseTrackVisibilityAction(GpxLayerTest.getMinimalGpxLayer()).actionPerformed(null);
     }
 }
Index: /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackActionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackActionTest.java	(revision 9948)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackActionTest.java	(revision 9949)
@@ -11,10 +11,9 @@
 import org.openstreetmap.josm.JOSMFixture;
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
+import org.openstreetmap.josm.gui.layer.GpxLayerTest;
 import org.openstreetmap.josm.gui.layer.TMSLayer;
 import org.openstreetmap.josm.gui.layer.gpx.DownloadWmsAlongTrackAction.PrecacheWmsTask;
-import org.openstreetmap.josm.io.GpxReaderTest;
 
 /**
@@ -52,6 +51,5 @@
             assertTrue(TMSLayer.getCache().getMatching(".*").isEmpty());
             // Perform action
-            final GpxData gpx = GpxReaderTest.parseGpxData(TestUtils.getTestDataRoot() + "minimal.gpx");
-            PrecacheWmsTask task = new DownloadWmsAlongTrackAction(gpx).createTask();
+            PrecacheWmsTask task = new DownloadWmsAlongTrackAction(GpxLayerTest.getMinimalGpxData()).createTask();
             assertNotNull(task);
             task.run();
