Index: /trunk/src/org/openstreetmap/josm/actions/RestartAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/RestartAction.java	(revision 8470)
+++ /trunk/src/org/openstreetmap/josm/actions/RestartAction.java	(revision 8471)
@@ -21,5 +21,6 @@
  * Restarts JOSM as it was launched. Comes from "restart" plugin, originally written by Upliner.
  * <br><br>
- * Mechanisms have been improved based on #8561 discussions and <a href="http://lewisleo.blogspot.jp/2012/08/programmatically-restart-java.html">this article</a>.
+ * Mechanisms have been improved based on #8561 discussions and
+ * <a href="http://lewisleo.blogspot.jp/2012/08/programmatically-restart-java.html">this article</a>.
  * @since 5857
  */
Index: /trunk/src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 8470)
+++ /trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 8471)
@@ -62,4 +62,6 @@
 import org.openstreetmap.josm.data.preferences.ColorProperty;
 import org.openstreetmap.josm.io.CachedFile;
+import org.openstreetmap.josm.io.OfflineAccessException;
+import org.openstreetmap.josm.io.OnlineResource;
 import org.openstreetmap.josm.io.XmlWriter;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -1449,7 +1451,26 @@
      * Replies the collection of plugin site URLs from where plugin lists can be downloaded.
      * @return the collection of plugin site URLs
+     * @see #getOnlinePluginSites
      */
     public Collection<String> getPluginSites() {
         return getCollection("pluginmanager.sites", Collections.singleton(Main.getJOSMWebsite()+"/pluginicons%<?plugins=>"));
+    }
+
+    /**
+     * Returns the list of plugin sites available according to offline mode settings.
+     * @return the list of available plugin sites
+     * @since 8471
+     */
+    public Collection<String> getOnlinePluginSites() {
+        Collection<String> pluginSites = new ArrayList<>(getPluginSites());
+        for (Iterator<String> it = pluginSites.iterator(); it.hasNext();) {
+            try {
+                OnlineResource.JOSM_WEBSITE.checkOfflineAccess(it.next(), Main.getJOSMWebsite());
+            } catch (OfflineAccessException ex) {
+                Main.warn(ex, false);
+                it.remove();
+            }
+        }
+        return pluginSites;
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java	(revision 8470)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java	(revision 8471)
@@ -50,6 +50,4 @@
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
-import org.openstreetmap.josm.io.OfflineAccessException;
-import org.openstreetmap.josm.io.OnlineResource;
 import org.openstreetmap.josm.plugins.PluginDownloadTask;
 import org.openstreetmap.josm.plugins.PluginInformation;
@@ -121,4 +119,5 @@
      * @param parent The parent component
      * @param task The finished plugin download task
+     * @param restartRequired true if a restart is required
      * @since 6797
      */
@@ -321,17 +320,4 @@
     }
 
-    private static Collection<String> getOnlinePluginSites() {
-        Collection<String> pluginSites = new ArrayList<>(Main.pref.getPluginSites());
-        for (Iterator<String> it = pluginSites.iterator(); it.hasNext();) {
-            try {
-                OnlineResource.JOSM_WEBSITE.checkOfflineAccess(it.next(), Main.getJOSMWebsite());
-            } catch (OfflineAccessException ex) {
-                Main.warn(ex.getMessage());
-                it.remove();
-            }
-        }
-        return pluginSites;
-    }
-
     /**
      * The action for downloading the list of available plugins
@@ -339,4 +325,7 @@
     class DownloadAvailablePluginsAction extends AbstractAction {
 
+        /**
+         * Constructs a new {@code DownloadAvailablePluginsAction}.
+         */
         public DownloadAvailablePluginsAction() {
             putValue(NAME,tr("Download list"));
@@ -347,5 +336,5 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            Collection<String> pluginSites = getOnlinePluginSites();
+            Collection<String> pluginSites = Main.pref.getOnlinePluginSites();
             if (pluginSites.isEmpty()) {
                 return;
@@ -369,5 +358,4 @@
             Main.worker.submit(continuation);
         }
-
     }
 
@@ -411,5 +399,6 @@
                     );
             // the async task for downloading plugin information
-            final ReadRemotePluginInformationTask pluginInfoDownloadTask = new ReadRemotePluginInformationTask(getOnlinePluginSites());
+            final ReadRemotePluginInformationTask pluginInfoDownloadTask = new ReadRemotePluginInformationTask(
+                    Main.pref.getOnlinePluginSites());
 
             // to be run asynchronously after the plugin download
Index: /trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 8470)
+++ /trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 8471)
@@ -53,4 +53,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.RestartAction;
 import org.openstreetmap.josm.data.Version;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
@@ -464,5 +465,5 @@
 
     /**
-     * Alerts the user if a plugin required by another plugin is missing
+     * Alerts the user if a plugin required by another plugin is missing, and offer to download them & restart JOSM
      *
      * @param parent The parent Component used to display error popup
@@ -471,5 +472,5 @@
      */
     private static void alertMissingRequiredPlugin(Component parent, String plugin, Set<String> missingRequiredPlugin) {
-        StringBuilder sb = new StringBuilder();
+        StringBuilder sb = new StringBuilder(48);
         sb.append("<html>")
           .append(trn("Plugin {0} requires a plugin which was not found. The missing plugin is:",
@@ -480,10 +481,81 @@
           .append(Utils.joinAsHtmlUnorderedList(missingRequiredPlugin))
           .append("</html>");
-        JOptionPane.showMessageDialog(
+        ButtonSpec[] specs = new ButtonSpec[] {
+                new ButtonSpec(
+                        tr("Download and restart"),
+                        ImageProvider.get("restart"),
+                        trn("Click to download missing plugin and restart JOSM",
+                            "Click to download missing plugins and restart JOSM",
+                            missingRequiredPlugin.size()),
+                        null /* no specific help text */
+                ),
+                new ButtonSpec(
+                        tr("Continue"),
+                        ImageProvider.get("ok"),
+                        trn("Click to continue without this plugin",
+                            "Click to continue without these plugins",
+                            missingRequiredPlugin.size()),
+                        null /* no specific help text */
+                )
+        };
+        if (0 == HelpAwareOptionPane.showOptionDialog(
                 parent,
                 sb.toString(),
                 tr("Error"),
-                JOptionPane.ERROR_MESSAGE
-        );
+                JOptionPane.ERROR_MESSAGE,
+                null, /* no special icon */
+                specs,
+                specs[0],
+                HelpUtil.ht("/Plugin/Loading#MissingRequiredPlugin"))) {
+            downloadRequiredPluginsAndRestart(parent, missingRequiredPlugin);
+        }
+    }
+
+    private static void downloadRequiredPluginsAndRestart(final Component parent, final Set<String> missingRequiredPlugin) {
+        // Update plugin list
+        final ReadRemotePluginInformationTask pluginInfoDownloadTask = new ReadRemotePluginInformationTask(
+                Main.pref.getOnlinePluginSites());
+        Main.worker.submit(pluginInfoDownloadTask);
+
+        // Continuation
+        Main.worker.submit(new Runnable() {
+            @Override
+            public void run() {
+                // Build list of plugins to download
+                Set<PluginInformation> toDownload = new HashSet<>(pluginInfoDownloadTask.getAvailablePlugins());
+                for (Iterator<PluginInformation> it = toDownload.iterator(); it.hasNext();) {
+                    PluginInformation info = it.next();
+                    if (!missingRequiredPlugin.contains(info.getName())) {
+                        it.remove();
+                    }
+                }
+                // Check if something has still to be downloaded
+                if (!toDownload.isEmpty()) {
+                    // download plugins
+                    final PluginDownloadTask task = new PluginDownloadTask(parent, toDownload, tr("Download plugins"));
+                    Main.worker.submit(task);
+                    Main.worker.submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            // restart if some plugins have been downloaded
+                            if (!task.getDownloadedPlugins().isEmpty()) {
+                                // update plugin list in preferences
+                                Set<String> plugins = new HashSet<>(Main.pref.getCollection("plugins"));
+                                for (PluginInformation plugin : task.getDownloadedPlugins()) {
+                                    plugins.add(plugin.name);
+                                }
+                                Main.pref.putCollection("plugins", plugins);
+                                // restart
+                                new RestartAction().actionPerformed(null);
+                            } else {
+                                Main.warn("No plugin downloaded, restart canceled");
+                            }
+                        }
+                    });
+                } else {
+                    Main.warn("No plugin to download, operation canceled");
+                }
+            }
+        });
     }
 
@@ -645,6 +717,5 @@
 
     /**
-     * Loads the plugin in <code>plugins</code> from locally available jar files into
-     * memory.
+     * Loads the plugin in <code>plugins</code> from locally available jar files into memory.
      *
      * @param parent The parent component to be used for the displayed dialog
@@ -905,5 +976,5 @@
             ReadRemotePluginInformationTask task1 = new ReadRemotePluginInformationTask(
                     monitor.createSubTaskMonitor(1, false),
-                    Main.pref.getPluginSites(), displayErrMsg
+                    Main.pref.getOnlinePluginSites(), displayErrMsg
             );
             Future<?> future = service.submit(task1);
@@ -1246,6 +1317,5 @@
         PluginProxy err = null;
         StackTraceElement[] stack = ex.getStackTrace();
-        /* remember the error position, as multiple plugins may be involved,
-           we search the topmost one */
+        // remember the error position, as multiple plugins may be involved, we search the topmost one
         int pos = stack.length;
         for (PluginProxy p : pluginList) {
