Index: trunk/src/org/openstreetmap/josm/gui/preferences/PluginPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/PluginPreference.java	(revision 5600)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/PluginPreference.java	(revision 5601)
@@ -284,5 +284,5 @@
                     SwingUtilities.invokeLater(new Runnable() {
                         public void run() {
-                            model.updateAvailablePlugins(task.getAvailabePlugins());
+                            model.updateAvailablePlugins(task.getAvailablePlugins());
                             pnlPluginPreferences.refreshView();
                             Main.pref.putInteger("pluginmanager.version", Version.getInstance().getVersion()); // fix #7030
@@ -374,5 +374,5 @@
                     if (pluginInfoDownloadTask.isCanceled())
                         return;
-                    model.updateAvailablePlugins(pluginInfoDownloadTask.getAvailabePlugins());
+                    model.updateAvailablePlugins(pluginInfoDownloadTask.getAvailablePlugins());
                     // select plugins which actually have to be updated
                     //
Index: trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginListPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginListPanel.java	(revision 5600)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginListPanel.java	(revision 5601)
@@ -118,9 +118,9 @@
             if (cb.isSelected() && cb.pi.requires != null) {
                 // Select required plugins
-                for (String s : cb.pi.requires.split(";")) {
-                    model.setPluginSelected(s.trim(), true);
+                for (String s : cb.pi.getRequiredPlugins()) {
+                    model.setPluginSelected(s, true);
                 }
                 // Alert user if plugin requirements are not met
-                PluginHandler.checkRequiredPluginsPreconditions(PluginListPanel.this, model.getAvailablePlugins(), cb.pi);
+                PluginHandler.checkRequiredPluginsPreconditions(PluginListPanel.this, model.getAvailablePlugins(), cb.pi, false);
             }
             // If the plugin has been unselected, was it required by other plugins still selected ?
@@ -129,6 +129,6 @@
                 for (PluginInformation pi : model.getAvailablePlugins()) {
                     if (!pi.equals(cb.pi) && pi.requires != null && model.isSelectedPlugin(pi.getName())) {
-                        for (String s : pi.requires.split(";")) {
-                            if (s.trim().equals(cb.pi.getName())) {
+                        for (String s : pi.getRequiredPlugins()) {
+                            if (s.equals(cb.pi.getName())) {
                                 otherPlugins.add(pi.getName()); 
                                 break;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java	(revision 5600)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java	(revision 5601)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.plugins.PluginException;
+import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.plugins.PluginInformation;
 
@@ -339,15 +340,8 @@
     public void refreshLocalPluginVersion(Collection<PluginInformation> plugins) {
         if (plugins == null) return;
-        File pluginDir = Main.pref.getPluginsDirectory();
         for (PluginInformation pi : plugins) {
-            // Find the downloaded file. We have tried to install the downloaded plugins
-            // (PluginHandler.installDownloadedPlugins). This succeeds depending on the
-            // platform.
-            File downloadedPluginFile = new File(pluginDir, pi.name + ".jar.new");
-            if (!(downloadedPluginFile.exists() && downloadedPluginFile.canRead())) {
-                downloadedPluginFile = new File(pluginDir, pi.name + ".jar");
-                if (!(downloadedPluginFile.exists() && downloadedPluginFile.canRead())) {
-                    continue;
-                }
+            File downloadedPluginFile = PluginHandler.findUpdatedJar(pi.name);
+            if (downloadedPluginFile == null) {
+                continue;
             }
             try {
@@ -358,5 +352,5 @@
                     continue;
                 }
-                oldinfo.localversion = newinfo.version;
+                oldinfo.updateLocalInfo(newinfo);
             } catch(PluginException e) {
                 e.printStackTrace();
Index: trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 5600)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 5601)
@@ -424,5 +424,5 @@
         }
 
-        return checkRequiredPluginsPreconditions(parent, plugins, plugin);
+        return checkRequiredPluginsPreconditions(parent, plugins, plugin, true);
     }
 
@@ -434,11 +434,15 @@
      * @param plugins the collection of all loaded plugins
      * @param plugin the plugin for which preconditions are checked
+     * @param local Determines if the local or up-to-date plugin dependencies are to be checked.
      * @return true, if the preconditions are met; false otherwise
-     */
-    public static boolean checkRequiredPluginsPreconditions(Component parent, Collection<PluginInformation> plugins, PluginInformation plugin) {
-
+     * @since 5601
+     */
+    public static boolean checkRequiredPluginsPreconditions(Component parent, Collection<PluginInformation> plugins, PluginInformation plugin, boolean local) {
+
+        String requires = local ? plugin.localrequires : plugin.requires;
+        
         // make sure the dependencies to other plugins are not broken
         //
-        if(plugin.requires != null){
+        if (requires != null) {
             Set<String> pluginNames = new HashSet<String>();
             for (PluginInformation pi: plugins) {
@@ -446,6 +450,6 @@
             }
             Set<String> missingPlugins = new HashSet<String>();
-            for (String requiredPlugin : plugin.requires.split(";")) {
-                requiredPlugin = requiredPlugin.trim();
+            List<String> requiredPlugins = local ? plugin.getLocalRequiredPlugins() : plugin.getRequiredPlugins();
+            for (String requiredPlugin : requiredPlugins) {
                 if (!pluginNames.contains(requiredPlugin)) {
                     missingPlugins.add(requiredPlugin);
@@ -730,4 +734,34 @@
         );
     }
+    
+    private static Set<PluginInformation> findRequiredPluginsToDownload(
+            Collection<PluginInformation> pluginsToUpdate, List<PluginInformation> allPlugins, Set<PluginInformation> pluginsToDownload) {
+        Set<PluginInformation> result = new HashSet<PluginInformation>();
+        for (PluginInformation pi : pluginsToUpdate) {
+            for (String name : pi.getRequiredPlugins()) {
+                try {
+                    PluginInformation installedPlugin = PluginInformation.findPlugin(name);
+                    if (installedPlugin == null) {
+                        // New required plugin is not installed, find its PluginInformation
+                        PluginInformation reqPlugin = null;
+                        for (PluginInformation pi2 : allPlugins) {
+                            if (pi2.getName().equals(name)) {
+                                reqPlugin = pi2;
+                                break;
+                            }
+                        }
+                        // Required plugin is known but not already on download list
+                        if (reqPlugin != null && !pluginsToDownload.contains(reqPlugin)) {
+                            result.add(reqPlugin);
+                        }
+                    }
+                } catch (PluginException e) {
+                    System.out.println(tr("Warning: failed to find plugin {0}", name));
+                    e.printStackTrace();
+                }
+            }
+        }
+        return result;
+    }
 
     /**
@@ -757,6 +791,9 @@
             );
             Future<?> future = service.submit(task1);
+            List<PluginInformation> allPlugins = null;
+            
             try {
                 future.get();
+                allPlugins = task1.getAvailablePlugins();
                 plugins = buildListOfPluginsToLoad(parent,monitor.createSubTaskMonitor(1, false));
             } catch(ExecutionException e) {
@@ -778,11 +815,29 @@
                 }
             }
-
+            
             if (!pluginsToUpdate.isEmpty()) {
+                
+                Set<PluginInformation> pluginsToDownload = new HashSet<PluginInformation>(pluginsToUpdate);
+                
+                if (allPlugins != null) {
+                    // Updated plugins may need additional plugin dependencies currently not installed
+                    //
+                    Set<PluginInformation> additionalPlugins = findRequiredPluginsToDownload(pluginsToUpdate, allPlugins, pluginsToDownload);
+                    pluginsToDownload.addAll(additionalPlugins);
+                    
+                    // Iterate on required plugins, if they need themselves another plugins (i.e A needs B, but B needs C)
+                    while (!additionalPlugins.isEmpty()) {
+                        // Install the additional plugins to load them later
+                        plugins.addAll(additionalPlugins);
+                        additionalPlugins = findRequiredPluginsToDownload(additionalPlugins, allPlugins, pluginsToDownload);
+                        pluginsToDownload.addAll(additionalPlugins);
+                    }
+                }
+
                 // try to update the locally installed plugins
                 //
                 PluginDownloadTask task2 = new PluginDownloadTask(
                         monitor.createSubTaskMonitor(1,false),
-                        pluginsToUpdate,
+                        pluginsToDownload,
                         tr("Update plugins")
                 );
@@ -800,4 +855,9 @@
                     return plugins;
                 }
+                
+                // Update Plugin info for downloaded plugins
+                //
+                refreshLocalUpdatedPluginInfo(task2.getDownloadedPlugins());
+                
                 // notify user if downloading a locally installed plugin failed
                 //
@@ -921,4 +981,45 @@
         return;
     }
+    
+    /**
+     * Replies the updated jar file for the given plugin name.
+     * @param name The plugin name to find.
+     * @return the updated jar file for the given plugin name. null if not found or not readable.
+     * @since 5601
+     */
+    public static File findUpdatedJar(String name) {
+        File pluginDir = Main.pref.getPluginsDirectory();
+        // Find the downloaded file. We have tried to install the downloaded plugins
+        // (PluginHandler.installDownloadedPlugins). This succeeds depending on the
+        // platform.
+        File downloadedPluginFile = new File(pluginDir, name + ".jar.new");
+        if (!(downloadedPluginFile.exists() && downloadedPluginFile.canRead())) {
+            downloadedPluginFile = new File(pluginDir, name + ".jar");
+            if (!(downloadedPluginFile.exists() && downloadedPluginFile.canRead())) {
+                return null;
+            }
+        }
+        return downloadedPluginFile;
+    }
+    
+    /**
+     * Refreshes the given PluginInformation objects with new contents read from their corresponding jar file.
+     * @param updatedPlugins The PluginInformation objects to update.
+     * @since 5601
+     */
+    public static void refreshLocalUpdatedPluginInfo(Collection<PluginInformation> updatedPlugins) {
+        if (updatedPlugins == null) return;
+        for (PluginInformation pi : updatedPlugins) {
+            File downloadedPluginFile = findUpdatedJar(pi.name);
+            if (downloadedPluginFile == null) {
+                continue;
+            }
+            try {
+                pi.updateFromJar(new PluginInformation(downloadedPluginFile, pi.name));
+            } catch(PluginException e) {
+                e.printStackTrace();
+            }
+        }
+    }
 
     private static boolean confirmDeactivatingPluginAfterException(PluginProxy plugin) {
Index: trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 5600)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 5601)
@@ -44,4 +44,5 @@
     public boolean oldmode = false;
     public String requires = null;
+    public String localrequires = null;
     public String link = null;
     public String description = null;
@@ -157,5 +158,24 @@
         this.attr.putAll(other.attr);
     }
-
+    
+    /**
+     * Updates the plugin information of this plugin information object with the
+     * plugin information in a plugin information object retrieved from a plugin
+     * jar.
+     *
+     * @param other the plugin information object retrieved from the jar file
+     * @since 5601
+     */
+    public void updateFromJar(PluginInformation other) {
+        updateLocalInfo(other);
+        if (other.icon != null) {
+            this.icon = other.icon;
+        }
+        this.early = other.early;
+        this.className = other.className;
+        this.libraries = other.libraries;
+        this.stage = other.stage;
+    }
+    
     private void scanManifest(Manifest manifest, boolean oldcheck){
         String lang = LanguageInfo.getLanguageCodeManifest();
@@ -452,4 +472,8 @@
     }
 
+    /**
+     * Replies the plugin icon, scaled to 24x24 pixels.
+     * @return the plugin icon, scaled to 24x24 pixels.
+     */
     public ImageIcon getScaledIcon() {
         if (icon == null)
@@ -462,3 +486,49 @@
         return getName();
     }
+
+    private static List<String> getRequiredPlugins(String pluginList) {
+        List<String> requiredPlugins = new ArrayList<String>();
+        if (pluginList != null) {
+            for (String s : pluginList.split(";")) {
+                String plugin = s.trim();
+                if (!plugin.isEmpty()) {
+                    requiredPlugins.add(plugin);
+                }
+            }
+        }
+        return requiredPlugins;
+    }
+    
+    /**
+     * Replies the list of plugins required by the up-to-date version of this plugin. 
+     * @return List of plugins required. Empty if no plugin is required.
+     * @since 5601
+     */
+    public List<String> getRequiredPlugins() {
+        return getRequiredPlugins(requires);
+    }
+    
+    /**
+     * Replies the list of plugins required by the local instance of this plugin. 
+     * @return List of plugins required. Empty if no plugin is required.
+     * @since 5601
+     */
+    public List<String> getLocalRequiredPlugins() {
+        return getRequiredPlugins(localrequires);
+    }
+    
+    /**
+     * Updates the local fields ({@link #localversion}, {@link #localmainversion}, {@link #localrequires}) 
+     * to values contained in the up-to-date fields ({@link #version}, {@link #mainversion}, {@link #requires}) 
+     * of the given PluginInformation.
+     * @param info The plugin information to get the data from.
+     * @since 5601
+     */
+    public void updateLocalInfo(PluginInformation info) {
+        if (info != null) {
+            this.localversion = info.version;
+            this.localmainversion = info.mainversion;
+            this.localrequires = info.requires;
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java	(revision 5600)
+++ trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java	(revision 5601)
@@ -63,19 +63,9 @@
         );
         if (!availablePlugins.containsKey(info.getName())) {
-            info.localversion = info.version;
-            info.localmainversion = info.mainversion;
+            info.updateLocalInfo(info);
             availablePlugins.put(info.getName(), info);
         } else {
             PluginInformation current = availablePlugins.get(info.getName());
-            current.localversion = info.version;
-            current.localmainversion = info.mainversion;
-            if (info.icon != null) {
-                current.icon = info.icon;
-            }
-            current.early = info.early;
-            current.className = info.className;
-            current.libraries = info.libraries;
-            current.stage = info.stage;
-            current.requires = info.requires;
+            current.updateFromJar(info);
         }
     }
Index: trunk/src/org/openstreetmap/josm/plugins/ReadRemotePluginInformationTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/ReadRemotePluginInformationTask.java	(revision 5600)
+++ trunk/src/org/openstreetmap/josm/plugins/ReadRemotePluginInformationTask.java	(revision 5601)
@@ -382,6 +382,7 @@
      *
      * @return  the list of plugins
-     */
-    public List<PluginInformation> getAvailabePlugins() {
+     * @since 5601
+     */
+    public List<PluginInformation> getAvailablePlugins() {
         return availablePlugins;
     }
