FELIX-6621 : Regressions caused by FELIX-6607
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java
index 2b2818c..c58294e 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java
@@ -29,6 +29,7 @@
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.Version;
 
 
@@ -263,4 +264,13 @@
             return Locale.getDefault();
         }
     }
+
+
+    public static String getStringProperty( final ServiceReference<?> service, final String propertyName ) {
+        final Object property = service.getProperty( propertyName );
+        if ( property instanceof String ) {
+            return ( String ) property;
+        }
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
index b122e11..d52ede4 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
@@ -63,7 +63,7 @@
 import org.apache.felix.webconsole.internal.core.BundlesServlet;
 import org.apache.felix.webconsole.internal.filter.FilteringResponseWrapper;
 import org.apache.felix.webconsole.internal.i18n.ResourceBundleManager;
-import org.apache.felix.webconsole.internal.servlet.PluginHolder.InternalPlugin;
+import org.apache.felix.webconsole.internal.servlet.Plugin.InternalPlugin;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
index 0b63c79..9ea34a5 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
@@ -20,6 +20,7 @@
 
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.NoSuchElementException;
 
 import javax.servlet.Servlet;
 import javax.servlet.ServletConfig;
@@ -27,9 +28,14 @@
 import javax.servlet.ServletException;
 
 import org.apache.felix.webconsole.AbstractWebConsolePlugin;
+import org.apache.felix.webconsole.WebConsoleConstants;
+import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
+import org.apache.felix.webconsole.internal.Util;
+import org.apache.felix.webconsole.internal.WebConsolePluginAdapter;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
 
 public abstract class Plugin implements ServletConfig, Comparable<Plugin> {
 
@@ -38,7 +44,9 @@
 
     private final ServiceReference<Servlet> serviceReference; // used for comparing conflicting services
 
-    private volatile String title;
+    protected volatile String title;
+
+    protected volatile String category;
 
     private volatile AbstractWebConsolePlugin consolePlugin;
 
@@ -52,8 +60,6 @@
         return this.serviceReference;
     }
 
-    public abstract String getId();
-
     public Bundle getBundle() {
         if ( this.serviceReference != null ) {
             return this.serviceReference.getBundle();
@@ -62,6 +68,22 @@
     }
 
     /**
+     * Initialize everything including title and category
+     */
+    public boolean init() {
+        final AbstractWebConsolePlugin plugin = this.doGetConsolePlugin();
+        if ( plugin != null ) {
+            try {
+                plugin.init(this);
+            } catch (final ServletException e) {
+                // ignore this
+            }
+            this.consolePlugin = plugin;
+        }
+        return this.getConsolePlugin() != null;
+    }
+
+    /**
      * Cleans up this plugin when it is not used any longer. This means
      * destroying the plugin servlet and, if it was registered as an OSGi
      * service, ungetting the service.
@@ -90,67 +112,42 @@
 
     @Override
     public int compareTo(final Plugin other) {
-        // serviceReference = null means internal (i.e. service.ranking=0 and service.id=0)
-        final Long id = serviceReference != null ? (Long) serviceReference.getProperty(Constants.SERVICE_ID) : 0;
-        final Long otherId = other.serviceReference != null ? (Long) other.serviceReference.getProperty(Constants.SERVICE_ID) : 0;
-        if (id.compareTo(otherId) == 0) {
-            return 0; // same service or both internal
+        int result = this.getLabel().compareTo(other.getLabel());
+        if (result == 0) {
+            // serviceReference = null means internal (i.e. service.ranking=0 and service.id=0)
+            final Long id = serviceReference != null ? (Long) serviceReference.getProperty(Constants.SERVICE_ID) : 0;
+            final Long otherId = other.serviceReference != null ? (Long) other.serviceReference.getProperty(Constants.SERVICE_ID) : 0;
+            result = id.compareTo(otherId);
+            if (result != 0) { // same service or both internal if 0
+                final Integer rank = getRanking(this.serviceReference);
+                final Integer otherRank = getRanking(other.serviceReference);
+                result = rank.compareTo(otherRank);
+                if (result == 0) {
+                    // If ranks are equal, then sort by service id in descending order.
+                    result = -1 * id.compareTo(otherId);
+                }
+            }
         }
-
-        final Integer rank = getRanking(this.serviceReference);
-        final Integer otherRank = getRanking(other.serviceReference);
-
-        // Sort by rank in ascending order.
-        if (rank.compareTo(otherRank) < 0) {
-            return -1; // lower rank
-        } else if (rank.compareTo(otherRank) > 0) {
-            return 1; // higher rank
-        }
-
-        // If ranks are equal, then sort by service id in descending order.
-        return -1 * id.compareTo(otherId);
-    }
-
-    protected PluginHolder getHolder() {
-        return holder;
+        return result;
     }
 
     public String getLabel() {
         return label;
     }
 
-    protected void setTitle(final String title ) {
-        this.title = title;
+    protected PluginHolder getHolder() {
+        return holder;
     }
 
     public String getTitle() {
         return this.title != null ? this.title : this.getLabel();
     }
 
-    // methods added to support categories
-
-    final String getCategory() {
-        return doGetCategory();
+    public String getCategory() {
+        return this.category;
     }
 
-    protected String doGetCategory() {
-        // get the service now
-        final AbstractWebConsolePlugin plugin = getConsolePlugin();
-        return ( plugin != null ) ? plugin.getCategory() : null;
-    }
-
-    public final AbstractWebConsolePlugin getConsolePlugin() {
-        if ( this.consolePlugin == null ) {
-            final AbstractWebConsolePlugin plugin = this.doGetConsolePlugin();
-            if ( plugin != null ) {
-                try {
-                    plugin.init(this);
-                } catch (final ServletException e) {
-                    // ignore this
-                }
-                this.consolePlugin = plugin;
-            }
-        }
+    public AbstractWebConsolePlugin getConsolePlugin() {
         return this.consolePlugin;
     }
 
@@ -158,6 +155,8 @@
         return true;
     }
 
+    public abstract String getId();
+
     protected abstract AbstractWebConsolePlugin doGetConsolePlugin();
 
     protected abstract void doUngetConsolePlugin( AbstractWebConsolePlugin consolePlugin );
@@ -183,4 +182,135 @@
     public String getServletName() {
         return getTitle();
     }
+
+    public static class ServletPlugin extends Plugin {
+
+        public ServletPlugin( final PluginHolder holder, final ServiceReference<Servlet> serviceReference, final String label ) {
+            super(holder, serviceReference, label);
+        }
+
+        public String getId() {
+            return this.getServiceReference().toString();
+        }
+
+        protected AbstractWebConsolePlugin doGetConsolePlugin() {
+            final Servlet service = getHolder().getBundleContext().getService( this.getServiceReference() );
+            if ( service != null ) {
+                this.title = Util.getStringProperty( this.getServiceReference(), WebConsoleConstants.PLUGIN_TITLE );
+                this.category = Util.getStringProperty( this.getServiceReference(), WebConsoleConstants.PLUGIN_CATEGORY );
+                final AbstractWebConsolePlugin servlet;
+                if ( service instanceof AbstractWebConsolePlugin ) {
+                    servlet = ( AbstractWebConsolePlugin ) service;
+                    if (this.title == null) {
+                        this.title = servlet.getTitle();
+                    }
+                    if (this.category == null) {
+                        this.category = servlet.getCategory();
+                    }
+                } else {
+                    servlet = new WebConsolePluginAdapter( getLabel(), service, this.getServiceReference() );
+                }
+                return servlet;
+            }
+            return null;
+        }
+
+        protected void doUngetConsolePlugin( AbstractWebConsolePlugin consolePlugin ) {
+            try {
+                getHolder().getBundleContext().ungetService( this.getServiceReference() );
+            } catch ( final IllegalStateException ise ) {
+                // ignore - bundle context is no longer valid
+            }
+        }
+
+        //---------- ServletConfig overwrite (based on ServletReference)
+
+        @Override
+        public String getInitParameter( final String name ) {
+            Object property = this.getServiceReference().getProperty( name );
+            if ( property != null && !property.getClass().isArray() ) {
+                return property.toString();
+            }
+
+            return super.getInitParameter( name );
+        }
+
+        @Override
+        public Enumeration<?> getInitParameterNames() {
+            final String[] keys = this.getServiceReference().getPropertyKeys();
+            return new Enumeration<Object>() {
+                int idx = 0;
+
+                public boolean hasMoreElements() {
+                    return idx < keys.length;
+                }
+
+                public Object nextElement() {
+                    if ( hasMoreElements() ) {
+                        return keys[idx++];
+                    }
+                    throw new NoSuchElementException();
+                }
+            };
+        }
+    }
+
+    public static class InternalPlugin extends Plugin {
+
+        private final String pluginClassName;
+        private final OsgiManager osgiManager;
+        private volatile boolean doLog = true;
+
+        public InternalPlugin(PluginHolder holder, OsgiManager osgiManager, String pluginClassName, String label) {
+            super(holder, null, label);
+            this.osgiManager = osgiManager;
+            this.pluginClassName = pluginClassName;
+        }
+
+        public String getId() {
+            return this.pluginClassName;
+        }
+
+        protected final boolean isEnabled() {
+            // check if the plugin is enabled
+            return !osgiManager.isPluginDisabled(pluginClassName);
+        }
+
+        protected AbstractWebConsolePlugin doGetConsolePlugin() {
+            if (!isEnabled()) {
+                if (doLog) {
+                    osgiManager.log( LogService.LOG_INFO, "Ignoring plugin " + pluginClassName + ": Disabled by configuration" );
+                    doLog = false;
+                }
+                return null;
+            }
+
+            AbstractWebConsolePlugin plugin = null;
+            try {
+                Class<?> pluginClass = getClass().getClassLoader().loadClass(pluginClassName);
+                plugin = (AbstractWebConsolePlugin) pluginClass.getDeclaredConstructor().newInstance();
+
+                if (plugin instanceof OsgiManagerPlugin) {
+                    ((OsgiManagerPlugin) plugin).activate(osgiManager.getBundleContext());
+                }
+                this.title = plugin.getTitle();
+                this.category = plugin.getCategory();
+                doLog = true; // reset logging if it succeeded
+            } catch (final Throwable t) {
+                plugin = null; // in case only activate has faled!
+                if (doLog) {
+                    osgiManager.log( LogService.LOG_WARNING, "Failed to instantiate plugin " + pluginClassName, t );
+                    doLog = false;
+                }
+            }
+
+            return plugin;
+        }
+
+        protected void doUngetConsolePlugin(final AbstractWebConsolePlugin plugin) {
+            if (plugin instanceof OsgiManagerPlugin) {
+                ((OsgiManagerPlugin) plugin).deactivate();
+            }
+        }
+    }
 }
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
index e7bbc25..05e69fd 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
@@ -20,12 +20,10 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.ResourceBundle;
 
 import javax.servlet.Servlet;
@@ -33,9 +31,10 @@
 
 import org.apache.felix.webconsole.AbstractWebConsolePlugin;
 import org.apache.felix.webconsole.WebConsoleConstants;
-import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
-import org.apache.felix.webconsole.internal.WebConsolePluginAdapter;
+import org.apache.felix.webconsole.internal.Util;
 import org.apache.felix.webconsole.internal.i18n.ResourceBundleManager;
+import org.apache.felix.webconsole.internal.servlet.Plugin.InternalPlugin;
+import org.apache.felix.webconsole.internal.servlet.Plugin.ServletPlugin;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
@@ -328,7 +327,7 @@
     @Override
     public Plugin addingService(final ServiceReference<Servlet> reference) {
         Plugin plugin = null;
-        final String label = getProperty( reference, WebConsoleConstants.PLUGIN_LABEL );
+        final String label = Util.getStringProperty( reference, WebConsoleConstants.PLUGIN_LABEL );
         if ( label != null ) {
             plugin = new ServletPlugin( this, reference, label );
             addPlugin( plugin );
@@ -357,11 +356,15 @@
             Collections.sort(list);
             Collections.reverse(list);
             final Plugin first = list.get(0);
-            if (first == plugin && oldPlugin != null) {
-                osgiManager.log(LogService.LOG_WARNING, "Overwriting existing plugin " + oldPlugin.getId() 
-                        + " having label " + plugin.getLabel() + " with new plugin " + plugin.getId()
-                        + " due to higher ranking " );
-                oldPlugin.dispose();
+            if (first == plugin) {
+                if (!first.init()) {
+                    list.remove(plugin);
+                } else if (oldPlugin != null) {
+                    osgiManager.log(LogService.LOG_WARNING, "Overwriting existing plugin " + oldPlugin.getId() 
+                            + " having label " + plugin.getLabel() + " with new plugin " + plugin.getId()
+                            + " due to higher ranking " );
+                    oldPlugin.dispose();
+                }
             }
             if (first == oldPlugin) {
                 osgiManager.log(LogService.LOG_WARNING, "Ignoring new plugin " + plugin.getId()
@@ -374,159 +377,17 @@
         synchronized ( plugins ) {
             final List<Plugin> list = plugins.get( plugin.getLabel() );
             if ( list != null ) {
+                final boolean isFirst = !list.isEmpty() && list.get(0) == plugin;
                 list.remove( plugin );
                 if ( list.isEmpty() ) {
                     plugins.remove( plugin.getLabel() );
+                } else if ( isFirst ) {
+                    while ( !list.isEmpty() && !list.get(0).init() ) {
+                        list.remove(0);
+                    }
                 }
             }
             plugin.dispose();
         }
     }
-
-    static String getProperty( final ServiceReference<?> service, final String propertyName ) {
-        final Object property = service.getProperty( propertyName );
-        if ( property instanceof String ) {
-            return ( String ) property;
-        }
-        return null;
-    }
-
-    private static class ServletPlugin extends Plugin {
-
-        ServletPlugin( final PluginHolder holder, final ServiceReference<Servlet> serviceReference, final String label ) {
-            super(holder, serviceReference, label);
-        }
-
-        public String getId() {
-            return this.getServiceReference().toString();
-        }
-
-        // added to support categories
-        protected String doGetCategory() {
-            // check service Reference
-            final String category = getProperty( this.getServiceReference(), WebConsoleConstants.PLUGIN_CATEGORY );
-            if ( category != null ) {
-                return category;
-            }
-
-            return super.doGetCategory();
-        }
-
-        protected AbstractWebConsolePlugin doGetConsolePlugin() {
-            final Servlet service = getHolder().getBundleContext().getService( this.getServiceReference() );
-            if ( service != null ) {
-                String title = getProperty( this.getServiceReference(), WebConsoleConstants.PLUGIN_TITLE );
-                final AbstractWebConsolePlugin servlet;
-                if ( service instanceof AbstractWebConsolePlugin ) {
-                    servlet = ( AbstractWebConsolePlugin ) service;
-                    if (title == null) {
-                        title = servlet.getTitle();
-                    }
-                } else {
-                    servlet = new WebConsolePluginAdapter( getLabel(), service, this.getServiceReference() );
-                }
-                this.setTitle(title);
-
-                return servlet;
-            }
-            return null;
-        }
-
-        protected void doUngetConsolePlugin( AbstractWebConsolePlugin consolePlugin ) {
-            try {
-                getHolder().getBundleContext().ungetService( this.getServiceReference() );
-            } catch ( final IllegalStateException ise ) {
-                // ignore - bundle context is no longer valid
-            }
-        }
-
-        //---------- ServletConfig overwrite (based on ServletReference)
-
-        @Override
-        public String getInitParameter( final String name ) {
-            Object property = this.getServiceReference().getProperty( name );
-            if ( property != null && !property.getClass().isArray() ) {
-                return property.toString();
-            }
-
-            return super.getInitParameter( name );
-        }
-
-        @Override
-        public Enumeration<?> getInitParameterNames() {
-            final String[] keys = this.getServiceReference().getPropertyKeys();
-            return new Enumeration<Object>() {
-                int idx = 0;
-
-                public boolean hasMoreElements() {
-                    return idx < keys.length;
-                }
-
-                public Object nextElement() {
-                    if ( hasMoreElements() ) {
-                        return keys[idx++];
-                    }
-                    throw new NoSuchElementException();
-                }
-            };
-        }
-    }
-
-    static class InternalPlugin extends Plugin {
-
-        private final String pluginClassName;
-        private final OsgiManager osgiManager;
-        private volatile boolean doLog = true;
-
-        protected InternalPlugin(PluginHolder holder, OsgiManager osgiManager, String pluginClassName, String label) {
-            super(holder, null, label);
-            this.osgiManager = osgiManager;
-            this.pluginClassName = pluginClassName;
-        }
-
-        public String getId() {
-            return this.pluginClassName;
-        }
-
-        protected final boolean isEnabled() {
-            // check if the plugin is enabled
-            return !osgiManager.isPluginDisabled(pluginClassName);
-        }
-
-        protected AbstractWebConsolePlugin doGetConsolePlugin() {
-            if (!isEnabled()) {
-                if (doLog) {
-                    osgiManager.log( LogService.LOG_INFO, "Ignoring plugin " + pluginClassName + ": Disabled by configuration" );
-                    doLog = false;
-                }
-                return null;
-            }
-
-            AbstractWebConsolePlugin plugin = null;
-            try {
-                Class<?> pluginClass = getClass().getClassLoader().loadClass(pluginClassName);
-                plugin = (AbstractWebConsolePlugin) pluginClass.getDeclaredConstructor().newInstance();
-
-                if (plugin instanceof OsgiManagerPlugin) {
-                    ((OsgiManagerPlugin) plugin).activate(osgiManager.getBundleContext());
-                }
-                this.setTitle(plugin.getTitle());
-                doLog = true; // reset logging if it succeeded
-            } catch (final Throwable t) {
-                plugin = null; // in case only activate has faled!
-                if (doLog) {
-                    osgiManager.log( LogService.LOG_WARNING, "Failed to instantiate plugin " + pluginClassName, t );
-                    doLog = false;
-                }
-            }
-
-            return plugin;
-        }
-
-        protected void doUngetConsolePlugin(final AbstractWebConsolePlugin plugin) {
-            if (plugin instanceof OsgiManagerPlugin) {
-                ((OsgiManagerPlugin) plugin).deactivate();
-            }
-        }
-    }
 }