Index: /trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 14548)
+++ /trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 14549)
@@ -15,4 +15,5 @@
 import java.util.Collections;
 import java.util.List;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -165,4 +166,55 @@
 
     /**
+     * Represents the user choices when selecting layers to display.
+     * @since 14549
+     */
+    public static class LayerSelection {
+        private final List<LayerDetails> layers;
+        private final String format;
+        private final boolean transparent;
+
+        /**
+         * Constructs a new {@code LayerSelection}.
+         * @param layers selected layers
+         * @param format selected image format
+         * @param transparent enable transparency?
+         */
+        public LayerSelection(List<LayerDetails> layers, String format, boolean transparent) {
+            this.layers = layers;
+            this.format = format;
+            this.transparent = transparent;
+        }
+    }
+
+    private static LayerSelection askToSelectLayers(WMSImagery wms) {
+        final WMSLayerTree tree = new WMSLayerTree();
+        tree.updateTree(wms);
+
+        Collection<String> wmsFormats = wms.getFormats();
+        final JComboBox<String> formats = new JComboBox<>(wmsFormats.toArray(new String[0]));
+        formats.setSelectedItem(wms.getPreferredFormat());
+        formats.setToolTipText(tr("Select image format for WMS layer"));
+
+        if (!GraphicsEnvironment.isHeadless()) {
+            ExtendedDialog dialog = new ExtendedDialog(MainApplication.getMainFrame(),
+                    tr("Select WMS layers"), tr("Add layers"), tr("Cancel"));
+            final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree());
+            scrollPane.setPreferredSize(new Dimension(400, 400));
+            final JPanel panel = new JPanel(new GridBagLayout());
+            panel.add(scrollPane, GBC.eol().fill());
+            panel.add(formats, GBC.eol().fill(GBC.HORIZONTAL));
+            dialog.setContent(panel);
+
+            if (dialog.showDialog().getValue() != 1) {
+                return null;
+            }
+        }
+        return new LayerSelection(
+                tree.getSelectedLayers(),
+                (String) formats.getSelectedItem(),
+                true); // TODO: ask the user if transparent layer is wanted
+    }
+
+    /**
      * Asks user to choose a WMS layer from a WMS endpoint.
      * @param info the WMS endpoint.
@@ -173,39 +225,35 @@
      */
     protected static ImageryInfo getWMSLayerInfo(ImageryInfo info) throws IOException, WMSGetCapabilitiesException {
+        return getWMSLayerInfo(info, AddImageryLayerAction::askToSelectLayers);
+    }
+
+    /**
+     * Asks user to choose a WMS layer from a WMS endpoint.
+     * @param info the WMS endpoint.
+     * @param choice how the user may choose the WMS layer
+     * @return chosen WMS layer, or null
+     * @throws IOException if any I/O error occurs while contacting the WMS endpoint
+     * @throws WMSGetCapabilitiesException if the WMS getCapabilities request fails
+     * @throws InvalidPathException if a Path object cannot be constructed for the capabilities cached file
+     * @since 14549
+     */
+    public static ImageryInfo getWMSLayerInfo(ImageryInfo info, Function<WMSImagery, LayerSelection> choice)
+            throws IOException, WMSGetCapabilitiesException {
         try {
             CheckParameterUtil.ensureThat(ImageryType.WMS_ENDPOINT == info.getImageryType(), "wms_endpoint imagery type expected");
             final WMSImagery wms = new WMSImagery(info.getUrl(), info.getCustomHttpHeaders());
-
-            final WMSLayerTree tree = new WMSLayerTree();
-            tree.updateTree(wms);
-
-            Collection<String> wmsFormats = wms.getFormats();
-            final JComboBox<String> formats = new JComboBox<>(wmsFormats.toArray(new String[0]));
-            formats.setSelectedItem(wms.getPreferredFormat());
-            formats.setToolTipText(tr("Select image format for WMS layer"));
-
-            if (!GraphicsEnvironment.isHeadless()) {
-                ExtendedDialog dialog = new ExtendedDialog(MainApplication.getMainFrame(),
-                        tr("Select WMS layers"), tr("Add layers"), tr("Cancel"));
-                final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree());
-                scrollPane.setPreferredSize(new Dimension(400, 400));
-                final JPanel panel = new JPanel(new GridBagLayout());
-                panel.add(scrollPane, GBC.eol().fill());
-                panel.add(formats, GBC.eol().fill(GBC.HORIZONTAL));
-                dialog.setContent(panel);
-
-                if (dialog.showDialog().getValue() != 1) {
-                    return null;
-                }
+            LayerSelection selection = choice.apply(wms);
+            if (selection == null) {
+                return null;
             }
 
             final String url = wms.buildGetMapUrl(
-                    tree.getSelectedLayers().stream().map(LayerDetails::getName).collect(Collectors.toList()),
+                    selection.layers.stream().map(LayerDetails::getName).collect(Collectors.toList()),
                     (List<String>) null,
-                    (String) formats.getSelectedItem(),
-                    true // TODO: ask the user if transparent layer is wanted
+                    selection.format,
+                    selection.transparent
                     );
 
-            String selectedLayers = tree.getSelectedLayers().stream()
+            String selectedLayers = selection.layers.stream()
                     .map(LayerDetails::getName)
                     .collect(Collectors.joining(", "));
@@ -215,5 +263,5 @@
             ret.setImageryType(ImageryType.WMS);
             ret.setName(info.getName() + selectedLayers);
-            ret.setServerProjections(wms.getServerProjections(tree.getSelectedLayers()));
+            ret.setServerProjections(wms.getServerProjections(selection.layers));
             return ret;
         } catch (MalformedURLException ex) {
Index: /trunk/test/unit/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreferenceTestIT.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreferenceTestIT.java	(revision 14548)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreferenceTestIT.java	(revision 14549)
@@ -30,4 +30,6 @@
 import org.openstreetmap.gui.jmapviewer.tilesources.TemplatedTMSTileSource;
 import org.openstreetmap.josm.TestUtils;
+import org.openstreetmap.josm.actions.AddImageryLayerAction;
+import org.openstreetmap.josm.actions.AddImageryLayerAction.LayerSelection;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -37,9 +39,9 @@
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
 import org.openstreetmap.josm.data.imagery.ImageryLayerInfo;
+import org.openstreetmap.josm.data.imagery.LayerDetails;
 import org.openstreetmap.josm.data.imagery.Shape;
 import org.openstreetmap.josm.data.imagery.TMSCachedTileLoaderJob;
 import org.openstreetmap.josm.data.imagery.TemplatedWMSTileSource;
 import org.openstreetmap.josm.data.imagery.TileJobOptions;
-import org.openstreetmap.josm.data.imagery.WMSEndpointTileSource;
 import org.openstreetmap.josm.data.imagery.WMTSTileSource;
 import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException;
@@ -47,4 +49,5 @@
 import org.openstreetmap.josm.data.projection.ProjectionRegistry;
 import org.openstreetmap.josm.data.projection.Projections;
+import org.openstreetmap.josm.io.imagery.WMSImagery.WMSGetCapabilitiesException;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 import org.openstreetmap.josm.tools.HttpClient;
@@ -245,5 +248,5 @@
                 checkTileUrl(info, tileSource, center, Utils.clamp(12, info.getMinZoom() + 1, info.getMaxZoom()));
             }
-        } catch (IOException | WMTSGetCapabilitiesException | IllegalArgumentException e) {
+        } catch (IOException | RuntimeException | WMSGetCapabilitiesException | WMTSGetCapabilitiesException e) {
             addError(info, info.getUrl() + " -> " + e.toString());
         }
@@ -264,5 +267,6 @@
     }
 
-    private static AbstractTileSource getTileSource(ImageryInfo info) throws IOException, WMTSGetCapabilitiesException {
+    private static AbstractTileSource getTileSource(ImageryInfo info)
+            throws IOException, WMTSGetCapabilitiesException, WMSGetCapabilitiesException {
         switch (info.getImageryType()) {
             case BING:
@@ -272,8 +276,8 @@
             case TMS:
                 return new TemplatedTMSTileSource(info);
+            case WMS_ENDPOINT:
+                info = convertWmsEndpointToWms(info); // fall-through
             case WMS:
                 return new TemplatedWMSTileSource(info, getProjection(info));
-            case WMS_ENDPOINT:
-                return new WMSEndpointTileSource(info, getProjection(info));
             case WMTS:
                 return new WMTSTileSource(info, getProjection(info));
@@ -281,4 +285,20 @@
                 throw new UnsupportedOperationException(info.toString());
         }
+    }
+
+    private static ImageryInfo convertWmsEndpointToWms(ImageryInfo info) throws IOException, WMSGetCapabilitiesException {
+        return AddImageryLayerAction.getWMSLayerInfo(
+                info, wms -> new LayerSelection(firstLeafLayer(wms.getLayers()), wms.getPreferredFormat(), true));
+    }
+
+    private static List<LayerDetails> firstLeafLayer(List<LayerDetails> layers) {
+        for (LayerDetails layer : layers) {
+            if (layer.getChildren().isEmpty()) {
+                return Collections.singletonList(layer);
+            } else {
+                return firstLeafLayer(layer.getChildren());
+            }
+        }
+        return Collections.emptyList();
     }
 
