Index: /trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/Main.java	(revision 6522)
+++ /trunk/src/org/openstreetmap/josm/Main.java	(revision 6523)
@@ -409,4 +409,7 @@
     }
 
+    /**
+     * Constructs new {@code Main} object. A lot of global variables are initialized here.
+     */
     public Main() {
         main = this;
Index: /trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 6522)
+++ /trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 6523)
@@ -7,4 +7,5 @@
 import gnu.getopt.LongOpt;
 
+import java.awt.Dimension;
 import java.awt.Image;
 import java.awt.Toolkit;
@@ -28,4 +29,5 @@
 
 import javax.swing.JFrame;
+import javax.swing.JOptionPane;
 import javax.swing.RepaintManager;
 import javax.swing.SwingUtilities;
@@ -33,10 +35,11 @@
 import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.PreferencesAction;
 import org.openstreetmap.josm.data.AutosaveTask;
 import org.openstreetmap.josm.data.CustomConfigurator;
-import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.Version;
 import org.openstreetmap.josm.gui.download.DownloadDialog;
 import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
+import org.openstreetmap.josm.gui.preferences.server.ProxyPreference;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.gui.util.GuiHelper;
@@ -340,5 +343,6 @@
         DefaultAuthenticator.createInstance();
         Authenticator.setDefault(DefaultAuthenticator.getInstance());
-        ProxySelector.setDefault(new DefaultProxySelector(ProxySelector.getDefault()));
+        DefaultProxySelector proxySelector = new DefaultProxySelector(ProxySelector.getDefault());
+        ProxySelector.setDefault(proxySelector);
         OAuthAccessTokenHolder.getInstance().init(Main.pref, CredentialsManager.getInstance());
 
@@ -407,38 +411,5 @@
         }
 
-        final Map<Option, Collection<String>> args_final = args;
-
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
-                    AutosaveTask autosaveTask = new AutosaveTask();
-                    List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
-                    if (!unsavedLayerFiles.isEmpty()) {
-                        ExtendedDialog dialog = new ExtendedDialog(
-                                Main.parent,
-                                tr("Unsaved osm data"),
-                                new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
-                                );
-                        dialog.setContent(
-                                trn("JOSM found {0} unsaved osm data layer. ",
-                                        "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
-                                        tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
-                        dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/delete"});
-                        int selection = dialog.showDialog().getValue();
-                        if (selection == 1) {
-                            autosaveTask.recoverUnsavedLayers();
-                        } else if (selection == 3) {
-                            autosaveTask.dicardUnsavedLayers();
-                        }
-                    }
-                    autosaveTask.schedule();
-                }
-
-                postConstructorProcessCmdLine(args_final);
-
-                DownloadDialog.autostartIfNeeded();
-            }
-        });
+        SwingUtilities.invokeLater(new GuiFinalizationWorker(args, proxySelector));
 
         if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) {
@@ -456,3 +427,85 @@
         }
     }
+
+    private static class GuiFinalizationWorker implements Runnable {
+
+        private final Map<Option, Collection<String>> args;
+        private final DefaultProxySelector proxySelector;
+
+        public GuiFinalizationWorker(Map<Option, Collection<String>> args, DefaultProxySelector proxySelector) {
+            this.args = args;
+            this.proxySelector = proxySelector;
+        }
+
+        @Override
+        public void run() {
+
+            // Handle proxy errors early to inform user he should change settings to be able to use JOSM correctly
+            handleProxyErrors();
+
+            // Restore autosave layers after crash and start autosave thread
+            handleAutosave();
+
+            // Handle command line instructions
+            postConstructorProcessCmdLine(args);
+
+            // Show download dialog if autostart is enabled
+            DownloadDialog.autostartIfNeeded();
+        }
+
+        private void handleAutosave() {
+            if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
+                AutosaveTask autosaveTask = new AutosaveTask();
+                List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
+                if (!unsavedLayerFiles.isEmpty()) {
+                    ExtendedDialog dialog = new ExtendedDialog(
+                            Main.parent,
+                            tr("Unsaved osm data"),
+                            new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
+                            );
+                    dialog.setContent(
+                            trn("JOSM found {0} unsaved osm data layer. ",
+                                    "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
+                                    tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
+                    dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/delete"});
+                    int selection = dialog.showDialog().getValue();
+                    if (selection == 1) {
+                        autosaveTask.recoverUnsavedLayers();
+                    } else if (selection == 3) {
+                        autosaveTask.dicardUnsavedLayers();
+                    }
+                }
+                autosaveTask.schedule();
+            }
+        }
+
+        private static String getHtmlList(Collection<String> set) {
+            StringBuilder sb = new StringBuilder("<ul>");
+            for (String s : set) {
+                sb.append("<li>"+s+"</li>");
+            }
+            return sb.append("</ul>").toString();
+        }
+
+        private void handleProxyErrors() {
+            if (proxySelector.hasErrors()) {
+                ExtendedDialog ed = new ExtendedDialog(
+                        Main.parent, tr("Proxy errors occured"),
+                        new String[]{tr("Change proxy settings"), tr("Cancel")});
+                ed.setButtonIcons(new String[]{"dialogs/settings.png", "cancel.png"}).setCancelButton(2);
+                ed.setMinimumSize(new Dimension(460, 260));
+                ed.setIcon(JOptionPane.WARNING_MESSAGE);
+                ed.setContent(tr("JOSM tried to access the following resources:")+
+                        "<br>"+getHtmlList(proxySelector.getErrorResources())+
+                        tr("but <b>failed</b> to do so, because of the following proxy errors:")+
+                        "<br>"+getHtmlList(proxySelector.getErrorMessages())+
+                        tr("Would you like to change your proxy settings now ?")
+                        );
+
+                if (ed.showDialog().getValue() == 1) {
+                    PreferencesAction.forPreferenceSubTab(null, null, ProxyPreference.class).run();
+                }
+            }
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java	(revision 6522)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java	(revision 6523)
@@ -45,4 +45,6 @@
 import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
 import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
+import org.openstreetmap.josm.gui.preferences.server.AuthenticationPreference;
+import org.openstreetmap.josm.gui.preferences.server.ProxyPreference;
 import org.openstreetmap.josm.gui.preferences.shortcut.ShortcutPreference;
 import org.openstreetmap.josm.plugins.PluginDownloadTask;
@@ -229,24 +231,56 @@
     }
 
+    /**
+     * Returns the {@code DisplayPreference} object.
+     * @return the {@code DisplayPreference} object.
+     */
     public final DisplayPreference getDisplayPreference() {
         return getSetting(DisplayPreference.class);
     }
 
+    /**
+     * Returns the {@code MapPreference} object.
+     * @return the {@code MapPreference} object.
+     */
     public final MapPreference getMapPreference() {
         return getSetting(MapPreference.class);
     }
 
+    /**
+     * Returns the {@code PluginPreference} object.
+     * @return the {@code PluginPreference} object.
+     */
     public final PluginPreference getPluginPreference() {
         return getSetting(PluginPreference.class);
     }
 
+    /**
+     * Returns the {@code ImageryPreference} object.
+     * @return the {@code ImageryPreference} object.
+     */
     public final ImageryPreference getImageryPreference() {
         return getSetting(ImageryPreference.class);
     }
 
+    /**
+     * Returns the {@code ShortcutPreference} object.
+     * @return the {@code ShortcutPreference} object.
+     */
     public final ShortcutPreference getShortcutPreference() {
         return getSetting(ShortcutPreference.class);
     }
 
+    /**
+     * Returns the {@code ServerAccessPreference} object.
+     * @return the {@code ServerAccessPreference} object.
+     * @since 6523
+     */
+    public final ServerAccessPreference getServerPreference() {
+        return getSetting(ServerAccessPreference.class);
+    }
+
+    /**
+     * Saves preferences.
+     */
     public void savePreferences() {
         if(Main.applet)
@@ -450,4 +484,6 @@
         settingsFactory.add(new LanguagePreference.Factory());
         settingsFactory.add(new ServerAccessPreference.Factory());
+        settingsFactory.add(new AuthenticationPreference.Factory());
+        settingsFactory.add(new ProxyPreference.Factory());
         settingsFactory.add(new MapPreference.Factory());
         settingsFactory.add(new ProjectionPreference.Factory());
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/ServerAccessPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/ServerAccessPreference.java	(revision 6522)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/ServerAccessPreference.java	(revision 6523)
@@ -8,4 +8,5 @@
 import java.awt.GridBagLayout;
 import java.awt.Insets;
+import java.beans.PropertyChangeListener;
 
 import javax.swing.JPanel;
@@ -14,11 +15,15 @@
 
 import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.preferences.server.AuthenticationPreferencesPanel;
 import org.openstreetmap.josm.gui.preferences.server.OsmApiUrlInputPanel;
-import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel;
 import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
 
+/**
+ * Connection preferences, including authentication and proxy sub-preferences.
+ */
 public final class ServerAccessPreference extends DefaultTabPreferenceSetting {
 
+    /**
+     * Factory used to create a new {@code ServerAccessPreference}.
+     */
     public static class Factory implements PreferenceSettingFactory {
         @Override
@@ -32,11 +37,6 @@
     }
 
+    /** indicates whether to use the default OSM URL or not */
     private OsmApiUrlInputPanel pnlApiUrlPreferences;
-
-    /** indicates whether to use the default OSM URL or not */
-    /** panel for configuring authentication preferences */
-    private AuthenticationPreferencesPanel pnlAuthPreferences;
-    /** panel for configuring proxy preferences */
-    private ProxyPreferencesPanel pnlProxyPreferences;
 
     /**
@@ -59,17 +59,5 @@
     protected JPanel buildTabbedServerPreferences() {
         JPanel pnl = new JPanel(new BorderLayout());
-
-        JTabbedPane tpServerPreferences = getTabPane();
-        pnlAuthPreferences = new AuthenticationPreferencesPanel();
-        tpServerPreferences.add(wrapVerticallyScrollablePanel(pnlAuthPreferences));
-        pnlProxyPreferences = new ProxyPreferencesPanel();
-        tpServerPreferences.add(wrapVerticallyScrollablePanel(pnlProxyPreferences));
-
-        tpServerPreferences.setTitleAt(0, tr("Authentication"));
-        tpServerPreferences.setTitleAt(1, tr("Proxy settings"));
-        tpServerPreferences.setToolTipTextAt(0, tr("Configure your identity and how to authenticate at the OSM server"));
-        tpServerPreferences.setToolTipTextAt(1, tr("Configure whether to use a proxy server"));
-
-        pnl.add(tpServerPreferences, BorderLayout.CENTER);
+        pnl.add(getTabPane(), BorderLayout.CENTER);
         return pnl;
     }
@@ -99,10 +87,15 @@
         pnl.add(buildTabbedServerPreferences(), gc);
 
-        // let the AuthPreferencesPanel know when the API URL changes
-        //
-        pnlApiUrlPreferences.addPropertyChangeListener(pnlAuthPreferences);
-
         HelpUtil.setHelpContext(pnl, HelpUtil.ht("/Preferences/Connection"));
         return pnl;
+    }
+
+    /**
+     * Adds a listener that will be notified of API URL change.
+     * @param listener the listener
+     * @since 6523
+     */
+    public final void addApiUrlChangeListener(PropertyChangeListener listener) {
+        pnlApiUrlPreferences.addPropertyChangeListener(listener);
     }
 
@@ -124,6 +117,4 @@
     public void initFromPreferences() {
         pnlApiUrlPreferences.initFromPreferences();
-        pnlAuthPreferences.initFromPreferences();
-        pnlProxyPreferences.initFromPreferences();
     }
 
@@ -134,6 +125,4 @@
     public boolean ok() {
         pnlApiUrlPreferences.saveToPreferences();
-        pnlAuthPreferences.saveToPreferences();
-        pnlProxyPreferences.saveToPreferences();
         return false;
     }
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreference.java	(revision 6523)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreference.java	(revision 6523)
@@ -0,0 +1,57 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.preferences.server;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
+import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
+import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
+
+/**
+ * Authentication sub-preferences in server preferences.
+ * @since 6523
+ */
+public class AuthenticationPreference implements SubPreferenceSetting {
+
+    /**
+     * Factory used to create a new {@code AuthenticationPreference}.
+     */
+    public static class Factory implements PreferenceSettingFactory {
+        @Override
+        public PreferenceSetting createPreferenceSetting() {
+            return new AuthenticationPreference();
+        }
+    }
+
+    AuthenticationPreferencesPanel pnlAuthPreferences;
+
+    private AuthenticationPreference() {
+        super();
+    }
+
+    @Override
+    public void addGui(PreferenceTabbedPane gui) {
+        pnlAuthPreferences = new AuthenticationPreferencesPanel();
+        gui.getServerPreference().addApiUrlChangeListener(pnlAuthPreferences);
+        gui.getServerPreference().addSubTab(this, tr("Authentication"), pnlAuthPreferences,
+                tr("Configure your identity and how to authenticate at the OSM server"));
+    }
+
+    @Override
+    public boolean ok() {
+        pnlAuthPreferences.saveToPreferences();
+        return false;
+    }
+
+    @Override
+    public boolean isExpert() {
+        return false;
+    }
+
+    @Override
+    public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
+        return gui.getServerPreference();
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/server/ProxyPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/server/ProxyPreference.java	(revision 6523)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/server/ProxyPreference.java	(revision 6523)
@@ -0,0 +1,56 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.preferences.server;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
+import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
+import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
+
+/**
+ * Proxy sub-preferences in server preferences.
+ * @since 6523
+ */
+public class ProxyPreference implements SubPreferenceSetting {
+
+    /**
+     * Factory used to create a new {@code ProxyPreference}.
+     */
+    public static class Factory implements PreferenceSettingFactory {
+        @Override
+        public PreferenceSetting createPreferenceSetting() {
+            return new ProxyPreference();
+        }
+    }
+
+    ProxyPreferencesPanel pnlProxyPreferences;
+
+    private ProxyPreference() {
+        super();
+    }
+
+    @Override
+    public void addGui(PreferenceTabbedPane gui) {
+        pnlProxyPreferences = new ProxyPreferencesPanel();
+        gui.getServerPreference().addSubTab(this, tr("Proxy settings"), pnlProxyPreferences,
+                tr("Configure whether to use a proxy server"));
+    }
+
+    @Override
+    public boolean ok() {
+        pnlProxyPreferences.saveToPreferences();
+        return false;
+    }
+
+    @Override
+    public boolean isExpert() {
+        return false;
+    }
+
+    @Override
+    public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
+        return gui.getServerPreference();
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java	(revision 6522)
+++ /trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java	(revision 6523)
@@ -12,5 +12,8 @@
 import java.net.URI;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
 
 import org.openstreetmap.josm.Main;
@@ -56,4 +59,7 @@
     private InetSocketAddress socksProxySocketAddress;
     private ProxySelector delegate;
+
+    private final Set<String> errorResources = new HashSet<String>();
+    private final Set<String> errorMessages = new HashSet<String>();
 
     /**
@@ -134,6 +140,44 @@
     public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
         // Just log something. The network stack will also throw an exception which will be caught somewhere else
-        //
         Main.error(tr("Connection to proxy ''{0}'' for URI ''{1}'' failed. Exception was: {2}", sa.toString(), uri.toString(), ioe.toString()));
+        // Remember errors to give a friendly user message asking to review proxy configuration
+        errorResources.add(uri.toString());
+        errorMessages.add(ioe.toString());
+    }
+
+    /**
+     * Returns the set of current proxy resources that failed to be retrieved.
+     * @return the set of current proxy resources that failed to be retrieved
+     * @since 6523
+     */
+    public final Set<String> getErrorResources() {
+        return new TreeSet<String>(errorResources);
+    }
+
+    /**
+     * Returns the set of current proxy error messages.
+     * @return the set of current proxy error messages
+     * @since 6523
+     */
+    public final Set<String> getErrorMessages() {
+        return new TreeSet<String>(errorMessages);
+    }
+
+    /**
+     * Clear the sets of failed resources and error messages.
+     * @since 6523
+     */
+    public final void clearErrors() {
+        errorResources.clear();
+        errorMessages.clear();
+    }
+
+    /**
+     * Determines if proxy errors have occured.
+     * @return {@code true} if errors have occured, {@code false} otherwise.
+     * @since 6523
+     */
+    public final boolean hasErrors() {
+        return !errorResources.isEmpty();
     }
 
