Index: src/org/openstreetmap/josm/gui/download/AbstractDownloadSourcePanel.java
===================================================================
--- src/org/openstreetmap/josm/gui/download/AbstractDownloadSourcePanel.java	(revision 12667)
+++ src/org/openstreetmap/josm/gui/download/AbstractDownloadSourcePanel.java	(working copy)
@@ -97,4 +97,13 @@
     public void triggerDownload(DownloadSettings downloadSettings) {
         getDownloadSource().doDownload(getData(), downloadSettings);
     }
+
+    /**
+     * Returns a simple name describing this panel. This string can be used from other GUI parts
+     * of JOSM to save the user preferences related to the GUI settings. For example, the panel for downloading
+     * the OSM data can be named 'downloadosmpanel'. Note, choose the name such that it is unique to avoid
+     * collisions with other names.
+     * @return A simple name describing this panel.
+     */
+    public abstract String getSimpleName();
 }
Index: src/org/openstreetmap/josm/gui/download/DownloadDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/download/DownloadDialog.java	(revision 12667)
+++ src/org/openstreetmap/josm/gui/download/DownloadDialog.java	(working copy)
@@ -15,6 +15,7 @@
 import java.awt.event.KeyEvent;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeListener;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -32,6 +33,8 @@
 import javax.swing.JSplitPane;
 import javax.swing.JTabbedPane;
 import javax.swing.KeyStroke;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.ExpertToggleAction;
@@ -49,6 +52,7 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OsmUrlToBounds;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -61,9 +65,9 @@
     /**
      * Preference properties
      */
+    private static final String TAB_SPLIT_NAMESPACE = "download.tabsplit.";
     private static final IntegerProperty DOWNLOAD_TAB = new IntegerProperty("download.tab", 0);
     private static final IntegerProperty DOWNLOAD_SOURCE_TAB = new IntegerProperty("download-source.tab", 0);
-    private static final IntegerProperty DIALOG_SPLIT = new IntegerProperty("download.split", 200);
     private static final BooleanProperty DOWNLOAD_AUTORUN = new BooleanProperty("download.autorun", false);
     private static final BooleanProperty DOWNLOAD_NEWLAYER = new BooleanProperty("download.newlayer", false);
     private static final BooleanProperty DOWNLOAD_ZOOMTODATA = new BooleanProperty("download.zoomtodata", true);
@@ -114,14 +118,10 @@
     protected final JPanel buildMainPanel() {
         mainPanel = new JPanel(new GridBagLayout());
 
-        downloadSources.add(new OSMDownloadSource());
-        downloadSources.add(new OverpassDownloadSource());
+        // add default download sources
+        addDownloadSource(new OSMDownloadSource());
+        addDownloadSource(new OverpassDownloadSource());
 
-        // register all default download sources
-        for (int i = 0; i < downloadSources.size(); i++) {
-            downloadSources.get(i).addGui(this);
-        }
-
         // must be created before hook
         slippyMapChooser = new SlippyMapChooser();
 
@@ -140,8 +140,8 @@
             s.addGui(this);
         }
 
-        // allow to collapse the panes completely
-        downloadSourcesTab.setMinimumSize(new Dimension(0, 0));
+        // allow to collapse the panes, but reserve some space for tabs
+        downloadSourcesTab.setMinimumSize(new Dimension(0, 25));
         tpDownloadAreaSelectors.setMinimumSize(new Dimension(0, 0));
 
         dialogSplit = new JSplitPane(
@@ -148,7 +148,12 @@
                 JSplitPane.VERTICAL_SPLIT,
                 downloadSourcesTab,
                 tpDownloadAreaSelectors);
+        dialogSplit.addPropertyChangeListener(getDividerChangedListener());
 
+        ChangeListener tabChangedListener = getDownloadSourceTabChangeListener();
+        tabChangedListener.stateChanged(new ChangeEvent(downloadSourcesTab));
+        downloadSourcesTab.addChangeListener(tabChangedListener);
+
         mainPanel.add(dialogSplit, GBC.eol().fill());
 
         cbNewLayer = new JCheckBox(tr("Download as new layer"));
@@ -252,6 +257,11 @@
         addWindowListener(new WindowEventHandler());
         ExpertToggleAction.addExpertModeChangeListener(expertListener);
         restoreSettings();
+
+        // if no bounding box is selected make sure it is still propagated.
+        if (currentBounds == null) {
+            boundingBoxChanged(null, null);
+        }
     }
 
     /**
@@ -314,7 +324,7 @@
 
     /**
      * Determines if the dialog autorun is enabled in preferences.
-     * @return {@code true} if the download dialog must be open at startup, {@code false} otherwise
+     * @return {@code true} if the download dialog must be open at startup, {@code false} otherwise.
      */
     public static boolean isAutorunEnabled() {
         return DOWNLOAD_AUTORUN.get();
@@ -321,10 +331,10 @@
     }
 
     /**
-     * Adds a new download area selector to the download dialog
+     * Adds a new download area selector to the download dialog.
      *
-     * @param selector the download are selector
-     * @param displayName the display name of the selector
+     * @param selector the download are selector.
+     * @param displayName the display name of the selector.
      */
     public void addDownloadAreaSelector(JPanel selector, String displayName) {
         tpDownloadAreaSelectors.add(displayName, selector);
@@ -331,12 +341,19 @@
     }
 
     /**
-     * Adds a new download source to the download dialog
+     * Adds a new download source to the download dialog if it is not added.
      *
      * @param downloadSource The download source to be added.
      * @param <T> The type of the download data.
+     * @throws JosmRuntimeException If the download source is already added. Note, download sources are
+     * compared by their reference.
      */
     public <T> void addDownloadSource(DownloadSource<T> downloadSource) {
+        if (downloadSources.contains(downloadSource)) {
+            throw new JosmRuntimeException("The download source you are trying to add already exists.");
+        }
+
+        downloadSources.add(downloadSource);
         if ((ExpertToggleAction.isExpert() && downloadSource.onlyExpert()) || !downloadSource.onlyExpert()) {
             addNewDownloadSourceTab(downloadSource);
         }
@@ -343,7 +360,7 @@
     }
 
     /**
-     * Refreshes the tile sources
+     * Refreshes the tile sources.
      * @since 6364
      */
     public final void refreshTileSources() {
@@ -358,7 +375,6 @@
     public void rememberSettings() {
         DOWNLOAD_TAB.put(tpDownloadAreaSelectors.getSelectedIndex());
         DOWNLOAD_SOURCE_TAB.put(downloadSourcesTab.getSelectedIndex());
-        DIALOG_SPLIT.put(dialogSplit.getDividerLocation());
         DOWNLOAD_NEWLAYER.put(cbNewLayer.isSelected());
         DOWNLOAD_ZOOMTODATA.put(cbZoomToDownloadedData.isSelected());
         if (currentBounds != null) {
@@ -373,7 +389,6 @@
         cbNewLayer.setSelected(DOWNLOAD_NEWLAYER.get());
         cbStartup.setSelected(isAutorunEnabled());
         cbZoomToDownloadedData.setSelected(DOWNLOAD_ZOOMTODATA.get());
-        dialogSplit.setDividerLocation(DIALOG_SPLIT.get());
 
         try {
             tpDownloadAreaSelectors.setSelectedIndex(DOWNLOAD_TAB.get());
@@ -407,7 +422,7 @@
 
     /**
      * Returns the previously saved bounding box from preferences.
-     * @return The bounding box saved in preferences if any, {@code null} otherwise
+     * @return The bounding box saved in preferences if any, {@code null} otherwise.
      * @since 6509
      */
     public static Bounds getSavedDownloadBounds() {
@@ -499,7 +514,7 @@
      * @param downloadSource The download source to be added.
      * @param <T> The type of the download data.
      */
-    private <T> void addNewDownloadSourceTab(DownloadSource<T> downloadSource) {
+    protected <T> void addNewDownloadSourceTab(DownloadSource<T> downloadSource) {
         AbstractDownloadSourcePanel<T> panel = downloadSource.createPanel();
         downloadSourcesTab.add(panel, downloadSource.getLabel());
         Icon icon = panel.getIcon();
@@ -535,6 +550,44 @@
     }
 
     /**
+     * Creates a listener that reacts on tab switches for {@code downloadSourcesTab} in order
+     * to adjust proper division of the dialog according to user saved preferences or minimal size
+     * of the panel.
+     * @return A listener to adjust dialog division.
+     */
+    private ChangeListener getDownloadSourceTabChangeListener() {
+        return ec -> {
+            JTabbedPane tabbedPane = (JTabbedPane) ec.getSource();
+            Component selectedComponent = tabbedPane.getSelectedComponent();
+            if (selectedComponent instanceof AbstractDownloadSourcePanel) {
+                AbstractDownloadSourcePanel<?> panel = (AbstractDownloadSourcePanel<?>) selectedComponent;
+                dialogSplit.setDividerLocation(Main.pref.getInteger(
+                        TAB_SPLIT_NAMESPACE + panel.getSimpleName(),
+                        panel.getMinimumSize().height));
+            }
+        };
+    }
+
+    /**
+     * Creates a listener that react on dialog splitters movements to save users preferences.
+     * @return A listener to save user preferred split of the dialog.
+     */
+    private PropertyChangeListener getDividerChangedListener() {
+        return evt -> {
+            if (evt.getPropertyName().equalsIgnoreCase(JSplitPane.DIVIDER_LOCATION_PROPERTY)) {
+                Component selectedComponent = downloadSourcesTab.getSelectedComponent();
+                if (selectedComponent instanceof AbstractDownloadSourcePanel) {
+                    AbstractDownloadSourcePanel<?> panel = (AbstractDownloadSourcePanel<?>) selectedComponent;
+                    Main.pref.put(
+                            TAB_SPLIT_NAMESPACE + panel.getSimpleName(),
+                            String.valueOf(dialogSplit.getDividerLocation())
+                    );
+                }
+            }
+        };
+    }
+
+    /**
      * Action that is executed when the cancel button is pressed.
      */
     class CancelAction extends AbstractAction {
@@ -554,9 +607,14 @@
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            AbstractDownloadSourcePanel<?> pnl = (AbstractDownloadSourcePanel<?>) downloadSourcesTab.getSelectedComponent();
-            run();
-            pnl.checkCancel();
+            Component panel = downloadSourcesTab.getSelectedComponent();
+            if (panel instanceof AbstractDownloadSourcePanel) {
+                AbstractDownloadSourcePanel<?> pnl = (AbstractDownloadSourcePanel<?>) panel;
+                run();
+                pnl.checkCancel();
+            } else {
+                run();
+            }
         }
     }
 
@@ -572,7 +630,8 @@
         }
 
         /**
-         * Starts the download, if possible
+         * Starts the download and closes the dialog, if all requirements for the current download source are met.
+         * Otherwise the download is not started and the dialog remains visible.
          */
         public void run() {
             Component panel = downloadSourcesTab.getSelectedComponent();
Index: src/org/openstreetmap/josm/gui/download/DownloadSettings.java
===================================================================
--- src/org/openstreetmap/josm/gui/download/DownloadSettings.java	(revision 12667)
+++ src/org/openstreetmap/josm/gui/download/DownloadSettings.java	(working copy)
@@ -1,10 +1,10 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.download;
 
+import org.openstreetmap.josm.data.Bounds;
+
 import java.util.Optional;
 
-import org.openstreetmap.josm.data.Bounds;
-
 /**
  * The global settings of {@link DownloadDialog}.
  * <p>
@@ -51,10 +51,6 @@
      * @return The bounds or an empty {@link Optional} if no bounds are selected
      */
     public Optional<Bounds> getDownloadBounds() {
-        if (downloadBounds == null) {
-            return Optional.empty();
-        } else {
-            return Optional.of(downloadBounds);
-        }
+        return Optional.ofNullable(downloadBounds);
     }
 }
Index: src/org/openstreetmap/josm/gui/download/DownloadSource.java
===================================================================
--- src/org/openstreetmap/josm/gui/download/DownloadSource.java	(revision 12667)
+++ src/org/openstreetmap/josm/gui/download/DownloadSource.java	(working copy)
@@ -30,12 +30,6 @@
     String getLabel();
 
     /**
-     * Add a download source to the dialog, see {@link DownloadDialog}.
-     * @param dialog The download dialog.
-     */
-    void addGui(DownloadDialog dialog);
-
-    /**
      * Defines whether this download source should be visible only in the expert mode.
      * @return Returns {@code true} if the download source should be visible only in the
      * expert mode, {@code false} otherwise.
Index: src/org/openstreetmap/josm/gui/download/OSMDownloadSource.java
===================================================================
--- src/org/openstreetmap/josm/gui/download/OSMDownloadSource.java	(revision 12667)
+++ src/org/openstreetmap/josm/gui/download/OSMDownloadSource.java	(working copy)
@@ -4,6 +4,7 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.Color;
+import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.GridBagLayout;
 import java.util.ArrayList;
@@ -117,11 +118,6 @@
     }
 
     @Override
-    public void addGui(DownloadDialog dialog) {
-        dialog.addDownloadSource(this);
-    }
-
-    @Override
     public boolean onlyExpert() {
         return false;
     }
@@ -137,13 +133,14 @@
         private final JCheckBox cbDownloadNotes;
         private final JLabel sizeCheck = new JLabel();
 
+        private static final String SIMPLE_NAME = "osmdownloadpanel";
         private static final BooleanProperty DOWNLOAD_OSM = new BooleanProperty("download.osm.data", true);
         private static final BooleanProperty DOWNLOAD_GPS = new BooleanProperty("download.osm.gps", false);
         private static final BooleanProperty DOWNLOAD_NOTES = new BooleanProperty("download.osm.notes", false);
 
         /**
-         * Creates a new {@link OSMDownloadSourcePanel}
-         * @param ds The osm download source the panel is for
+         * Creates a new {@link OSMDownloadSourcePanel}.
+         * @param ds The osm download source the panel is for.
          */
         public OSMDownloadSourcePanel(OSMDownloadSource ds) {
             super(ds);
@@ -174,6 +171,8 @@
             add(cbDownloadGpxData, GBC.std().insets(1, 5, 1, 5));
             add(cbDownloadNotes, GBC.eol().insets(1, 5, 1, 5));
             add(sizeCheck, GBC.eol().anchor(GBC.EAST).insets(5, 5, 5, 2));
+
+            setMinimumSize(new Dimension(450, 115));
         }
 
         @Override
@@ -277,12 +276,20 @@
             updateSizeCheck(bbox);
         }
 
+        @Override
+        public String getSimpleName() {
+            return SIMPLE_NAME;
+        }
+
         private void updateSizeCheck(Bounds bbox) {
-            boolean isAreaTooLarge = false;
             if (bbox == null) {
                 sizeCheck.setText(tr("No area selected yet"));
                 sizeCheck.setForeground(Color.darkGray);
-            } else if (!isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
+                return;
+            }
+
+            boolean isAreaTooLarge = false;
+            if (!isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
                 isAreaTooLarge = false;
             } else if (isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
                 // see max_note_request_area in https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
Index: src/org/openstreetmap/josm/gui/download/OverpassDownloadSource.java
===================================================================
--- src/org/openstreetmap/josm/gui/download/OverpassDownloadSource.java	(revision 12667)
+++ src/org/openstreetmap/josm/gui/download/OverpassDownloadSource.java	(working copy)
@@ -70,11 +70,6 @@
     }
 
     @Override
-    public void addGui(DownloadDialog dialog) {
-        dialog.addDownloadSource(this);
-    }
-
-    @Override
     public boolean onlyExpert() {
         return true;
     }
@@ -88,6 +83,7 @@
         private JosmTextArea overpassQuery;
         private OverpassQueryList overpassQueryList;
 
+        private static final String SIMPLE_NAME = "overpassdownloadpanel";
         private static final BooleanProperty OVERPASS_QUERY_LIST_OPENED =
                 new BooleanProperty("download.overpass.query-list.opened", false);
         private static final String ACTION_IMG_SUBDIR = "dialogs";
@@ -179,6 +175,8 @@
             add(leftPanel, BorderLayout.WEST);
             add(innerPanel, BorderLayout.CENTER);
             add(listPanel, BorderLayout.EAST);
+
+            setMinimumSize(new Dimension(450, 240));
         }
 
         @Override
@@ -274,6 +272,11 @@
             return ImageProvider.get("download-overpass");
         }
 
+        @Override
+        public String getSimpleName() {
+            return SIMPLE_NAME;
+        }
+
         /**
          * Action that delegates snippet creation to {@link OverpassQueryList#createNewItem()}.
          */
