Refactor navigation stuff to be more elastic. ConsoleTab is replaced by ConsoleTabProvider which may decorate returned links.

git-svn-id: https://svn.apache.org/repos/asf/karaf/sandbox/webconsole/trunk@1164475 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/blueprint/src/main/java/org/apache/karaf/webconsole/blueprint/internal/navigation/BlueprintNavigationProvider.java b/blueprint/src/main/java/org/apache/karaf/webconsole/blueprint/internal/navigation/BlueprintNavigationProvider.java
index ee09614..c26e667 100644
--- a/blueprint/src/main/java/org/apache/karaf/webconsole/blueprint/internal/navigation/BlueprintNavigationProvider.java
+++ b/blueprint/src/main/java/org/apache/karaf/webconsole/blueprint/internal/navigation/BlueprintNavigationProvider.java
@@ -16,18 +16,32 @@
  */
 package org.apache.karaf.webconsole.blueprint.internal.navigation;
 
-import java.util.HashMap;
-import java.util.Map;
+import static org.apache.wicket.model.Model.of;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.karaf.webconsole.blueprint.internal.BlueprintPage;
 import org.apache.karaf.webconsole.core.navigation.NavigationProvider;
 import org.apache.wicket.Page;
+import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.markup.html.CSSPackageResource;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.link.Link;
 
 public class BlueprintNavigationProvider implements NavigationProvider {
 
-    public Map<String, Class<? extends Page>> getItems() {
-        Map<String, Class<? extends Page>> items = new HashMap<String, Class<? extends Page>>();
-        items.put("blueprint", BlueprintPage.class);
+    public List<Link<Page>> getItems(String componentId, String labelId) {
+        List<Link<Page>> items = new ArrayList<Link<Page>>();
+
+        Link<Page> link = new BookmarkablePageLink<Page>(componentId, BlueprintPage.class);
+        Label label = new Label(labelId, "Blueprint");
+        label.add(new AttributeAppender("class", of("blueprint"), " "));
+        link.add(label);
+        link.add(CSSPackageResource.getHeaderContribution(BlueprintPage.class, "navigation.css"));
+        items.add(link);
+
         return items;
     }
 
diff --git a/blueprint/src/main/resources/org/apache/karaf/webconsole/blueprint/internal/navigation.css b/blueprint/src/main/resources/org/apache/karaf/webconsole/blueprint/internal/navigation.css
new file mode 100644
index 0000000..40ccfd1
--- /dev/null
+++ b/blueprint/src/main/resources/org/apache/karaf/webconsole/blueprint/internal/navigation.css
@@ -0,0 +1,4 @@
+#topmenu ul li span.blueprint {
+    padding-left: 16px;
+    background: url("bundle/blueprint.gif") no-repeat;
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/BasePage.java b/core/src/main/java/org/apache/karaf/webconsole/core/BasePage.java
index c942040..1444c95 100644
--- a/core/src/main/java/org/apache/karaf/webconsole/core/BasePage.java
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/BasePage.java
@@ -22,7 +22,7 @@
 
 import org.apache.karaf.webconsole.core.brand.BrandProvider;
 import org.apache.karaf.webconsole.core.internal.LanguagePanel;
-import org.apache.karaf.webconsole.core.navigation.ConsoleTab;
+import org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider;
 import org.apache.karaf.webconsole.core.navigation.markup.NavigationPanel;
 import org.apache.wicket.behavior.IBehavior;
 import org.apache.wicket.markup.html.CSSPackageResource;
@@ -37,7 +37,7 @@
 public class BasePage extends WebPage {
 
     @PaxWicketBean(name = "tabs")
-    private List<ConsoleTab> tabs;
+    private List<ConsoleTabProvider> tabs;
 
     @PaxWicketBean(name = "brandProvider")
     private BrandProvider brandProvider;
@@ -56,9 +56,9 @@
 
         add(new LanguagePanel("languagePanel", supportedLocales));
 
-       add(new NavigationPanel("navigationPanel", new LoadableDetachableModel<List<ConsoleTab>>() {
+       add(new NavigationPanel("navigationPanel", new LoadableDetachableModel<List<ConsoleTabProvider>>() {
             @Override
-            protected List<ConsoleTab> load() {
+            protected List<ConsoleTabProvider> load() {
                 return tabs;
             }
         }));
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/BasePage2.java b/core/src/main/java/org/apache/karaf/webconsole/core/BasePage2.java
deleted file mode 100644
index 8cfd2f1..0000000
--- a/core/src/main/java/org/apache/karaf/webconsole/core/BasePage2.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.webconsole.core;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.karaf.webconsole.core.navigation.ConsoleTab;
-import org.apache.wicket.ResourceReference;
-import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
-import org.apache.wicket.extensions.markup.html.tabs.TabbedPanel;
-import org.apache.wicket.markup.html.CSSPackageResource;
-import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.image.Image;
-import org.apache.wicket.markup.html.link.PageLink;
-import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.model.Model;
-import org.ops4j.pax.wicket.api.PaxWicketBean;
-
-public class BasePage2 extends WebPage {
-
-    @PaxWicketBean(name = "tabs")
-    private List<ConsoleTab> tabs;
-
-    public BasePage2() {
-        add(CSSPackageResource.getHeaderContribution(BasePage2.class, "style.css"));
-        add(CSSPackageResource.getHeaderContribution(BasePage2.class, "grid.css"));
-
-        add(new Label("footer", "Apache Karaf Console"));
-
-        add(new Image("karafLogo", new ResourceReference(BasePage2.class, "images/karaf-logo.png")));
-
-        add(new ListView<ConsoleTab>("tabs", tabs) {
-            @Override
-            protected void populateItem(ListItem<ConsoleTab> item) {
-                final ConsoleTab tab = item.getModelObject();
-                item.add(new PageLink("moduleLink", tab.getModuleHomePage()).add(new Label("moduleLabel", tab.getLabel())));
-
-                List<String> subItems = new LinkedList<String>(tab.getItems().keySet());
-                item.add(new ListView<String>("topLinks", subItems) {
-                    @Override
-                    protected void populateItem(ListItem<String> item) {
-                        String subItem = item.getModelObject();
-                        item.add(new PageLink("topLink", tab.getItems().get(subItem)).add(new Label("linkLabel", subItem)));
-                    }
-                });
-            }
-        });
-
-        List tabPanels = new ArrayList();
-        tabPanels.add(new AbstractTab(new Model("first tab")) {
-            public Panel getPanel(String panelId) {
-                return new TabPanel1(panelId);
-            }
-        });
-
-        add(new TabbedPanel("tabPanels", tabPanels));
-
-    }
-
-
-    class TabPanel1 extends Panel {
-        public TabPanel1(String id) {
-            super(id);
-        }
-    }
-
-}
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/internal/SystemConsoleTab.java b/core/src/main/java/org/apache/karaf/webconsole/core/internal/SystemConsoleTab.java
deleted file mode 100644
index b115bff..0000000
--- a/core/src/main/java/org/apache/karaf/webconsole/core/internal/SystemConsoleTab.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.webconsole.core.internal;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.karaf.webconsole.core.dashboard.DashboardPage;
-import org.apache.karaf.webconsole.core.navigation.ConsoleTab;
-import org.apache.wicket.Page;
-
-public class SystemConsoleTab implements ConsoleTab, Serializable {
-
-    public String getLabel() {
-        return "dashboard";
-    }
-
-    public Class<? extends Page> getModuleHomePage() {
-        return DashboardPage.class;
-    }
-
-    public Map<String, Class<? extends Page>> getItems() {
-        Map<String, Class<? extends Page>> map = new HashMap<String, Class<? extends Page>>();
-        map.put("dashboard", DashboardPage.class);
-        return map;
-    }
-
-}
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/internal/SystemConsoleTabProvider.java b/core/src/main/java/org/apache/karaf/webconsole/core/internal/SystemConsoleTabProvider.java
new file mode 100644
index 0000000..2cf916f
--- /dev/null
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/internal/SystemConsoleTabProvider.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.webconsole.core.internal;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.karaf.webconsole.core.dashboard.DashboardPage;
+import org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider;
+import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.link.Link;
+
+public class SystemConsoleTabProvider implements ConsoleTabProvider, Serializable {
+
+    public Link<Page> getModuleLink(String componentId, String labelId) {
+        Link<Page> link = new BookmarkablePageLink<Page>(componentId, DashboardPage.class);
+        link.add(new Label(labelId, "Dashboard"));
+        return link;
+    }
+
+    public List<Link<Page>> getItems(String componentId, String labelId) {
+        return Collections.emptyList();
+    }
+
+}
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/ConsoleTab.java b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/ConsoleTabProvider.java
similarity index 70%
rename from core/src/main/java/org/apache/karaf/webconsole/core/navigation/ConsoleTab.java
rename to core/src/main/java/org/apache/karaf/webconsole/core/navigation/ConsoleTabProvider.java
index ccf02d8..f925079 100644
--- a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/ConsoleTab.java
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/ConsoleTabProvider.java
@@ -17,15 +17,21 @@
 package org.apache.karaf.webconsole.core.navigation;
 
 import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.link.Link;
 
 /**
  * Console tab is top level extension of webconsole. It may provide new elements
- * to navigation and should have label to be rendered in top menu.
+ * to navigation.
  */
-public interface ConsoleTab extends NavigationProvider {
+public interface ConsoleTabProvider extends NavigationProvider {
 
-    String getLabel();
-
-    Class<? extends Page> getModuleHomePage();
+    /**
+     * Gets module home link.
+     * 
+     * @param componentId Identifier of created link.
+     * @param labelId Identifier of label inside link.
+     * @return Link to module home page.
+     */
+    Link<Page> getModuleLink(String componentId, String labelId);
 
 }
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/ExtendableConsoleTab.java b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/ExtendableConsoleTabProvider.java
similarity index 64%
rename from core/src/main/java/org/apache/karaf/webconsole/core/navigation/ExtendableConsoleTab.java
rename to core/src/main/java/org/apache/karaf/webconsole/core/navigation/ExtendableConsoleTabProvider.java
index 6f3340f..decca02 100644
--- a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/ExtendableConsoleTab.java
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/ExtendableConsoleTabProvider.java
@@ -16,37 +16,36 @@
  */
 package org.apache.karaf.webconsole.core.navigation;
 
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Map;
+import java.util.List;
 
 import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.link.Link;
 
 /**
  * Implementation of console tab which allows external providers to put own
  * items to it.
  */
-public class ExtendableConsoleTab implements ConsoleTab {
+public class ExtendableConsoleTabProvider implements ConsoleTabProvider {
 
     private Collection<NavigationProvider> extensions;
-    private ConsoleTab base;
+    private ConsoleTabProvider base;
 
-    public ExtendableConsoleTab(ConsoleTab base) {
+    public ExtendableConsoleTabProvider(ConsoleTabProvider base) {
         this.base = base;
     }
 
-    public String getLabel() {
-        return base.getLabel();
+    public Link<Page> getModuleLink(String componentId, String labelId) {
+        return base.getModuleLink(componentId, labelId);
     }
 
-    public Class<? extends Page> getModuleHomePage() {
-        return base.getModuleHomePage();
-    }
-
-    public Map<String, Class<? extends Page>> getItems() {
-        Map<String, Class<? extends Page>> items = base.getItems();
+    public List<Link<Page>> getItems(String componentId, String labelId) {
+        // create new list because instance returned from base provider may be read only..
+        List<Link<Page>> items = new ArrayList<Link<Page>>(base.getItems(componentId, labelId));
 
         for (NavigationProvider provider : extensions) {
-            items.putAll(provider.getItems());
+            items.addAll(provider.getItems(componentId, labelId));
         }
 
         return items;
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/NavigationProvider.java b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/NavigationProvider.java
index b29340e..8858918 100644
--- a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/NavigationProvider.java
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/NavigationProvider.java
@@ -17,9 +17,10 @@
 package org.apache.karaf.webconsole.core.navigation;
 
 import java.io.Serializable;
-import java.util.Map;
+import java.util.List;
 
 import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.link.Link;
 
 /**
  * Base extension point in console. Allow suppliers to ship new navigation
@@ -28,11 +29,12 @@
 public interface NavigationProvider extends Serializable {
 
     /**
-     * Return list of pages to add in navigation. Key in collection is element
-     * label.
+     * Return list of links to pages to add in navigation. 
+     * @param componentId Identifier of the link.
+     * @param labelId Identifier of link label.
      * 
      * @return Pages to add in navigation.
      */
-    Map<String, Class<? extends Page>> getItems();
+    List<Link<Page>> getItems(String componentId, String labelId);
 
 }
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/i18n/LocalizableConsoleTab.java b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/i18n/LocalizableConsoleTab.java
deleted file mode 100644
index 4ae9e02..0000000
--- a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/i18n/LocalizableConsoleTab.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.webconsole.core.navigation.i18n;
-
-import org.apache.karaf.webconsole.core.navigation.ConsoleTab;
-import org.apache.wicket.Page;
-import org.apache.wicket.model.ResourceModel;
-
-public class LocalizableConsoleTab extends LocalizableNavigationProvider implements ConsoleTab {
-
-    private ConsoleTab provider;
-
-    public LocalizableConsoleTab(ConsoleTab provider) {
-        super(provider);
-        this.provider = provider;
-    }
-
-    public String getLabel() {
-        return new ResourceModel(provider.getLabel(), provider.getLabel()).getObject();
-    }
-
-    public Class<? extends Page> getModuleHomePage() {
-        return provider.getModuleHomePage();
-    }
-
-}
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/i18n/LocalizableNavigationProvider.java b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/i18n/LocalizableNavigationProvider.java
deleted file mode 100644
index b9db572..0000000
--- a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/i18n/LocalizableNavigationProvider.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.webconsole.core.navigation.i18n;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.karaf.webconsole.core.navigation.NavigationProvider;
-import org.apache.wicket.Page;
-import org.apache.wicket.model.ResourceModel;
-
-public class LocalizableNavigationProvider implements NavigationProvider {
-
-    private final NavigationProvider provider;
-
-
-    public LocalizableNavigationProvider(NavigationProvider provider) {
-        this.provider = provider;
-    }
-
-
-    public Map<String, Class<? extends Page>> getItems() {
-        Map<String, Class<? extends Page>> items = new HashMap<String, Class<? extends Page>>();
-
-        for (Entry<String, Class<? extends Page>> entry : provider.getItems().entrySet()) {
-            items.put(new ResourceModel(entry.getKey(), entry.getKey()).getObject(), entry.getValue());
-        }
-
-        return items;
-    }
-
-}
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/markup/NavigationPanel.java b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/markup/NavigationPanel.java
index e67bf7e..4eb4299 100644
--- a/core/src/main/java/org/apache/karaf/webconsole/core/navigation/markup/NavigationPanel.java
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/navigation/markup/NavigationPanel.java
@@ -16,15 +16,11 @@
  */
 package org.apache.karaf.webconsole.core.navigation.markup;
 
-import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Map.Entry;
 
-import org.apache.karaf.webconsole.core.navigation.ConsoleTab;
+import org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider;
 import org.apache.wicket.Page;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.markup.html.panel.Panel;
@@ -35,28 +31,20 @@
  */
 public class NavigationPanel extends Panel {
 
-    public NavigationPanel(String id, IModel<List<ConsoleTab>> model) {
+    public NavigationPanel(String id, IModel<List<ConsoleTabProvider>> model) {
         super(id);
 
-        add(new ListView<ConsoleTab>("tabs", model) {
+        add(new ListView<ConsoleTabProvider>("tabs", model) {
             @Override
-            protected void populateItem(ListItem<ConsoleTab> item) {
-                ConsoleTab tab = item.getModelObject();
+            protected void populateItem(ListItem<ConsoleTabProvider> item) {
+                ConsoleTabProvider tab = item.getModelObject();
 
-                item.add(new BookmarkablePageLink("moduleLink", tab.getModuleHomePage()).add(new Label("moduleLabel",
-                    tab.getLabel())));
+                item.add(tab.getModuleLink("moduleLink", "moduleLabel"));
 
-                List<SimplifiedModel> model = new ArrayList<NavigationPanel.SimplifiedModel>();
-                for (Entry<String, Class<? extends Page>> entries : tab.getItems().entrySet()) {
-                    model.add(new SimplifiedModel(entries.getKey(), entries.getValue()));
-                }
-
-                item.add(new ListView<SimplifiedModel>("topLinks", model) {
+                item.add(new ListView<Link<Page>>("moduleLinks", tab.getItems("link", "label")) {
                     @Override
-                    protected void populateItem(ListItem<SimplifiedModel> item) {
-                        SimplifiedModel subItem = item.getModelObject();
-                        item.add(new BookmarkablePageLink("topLink", subItem.getClazz()).add(new Label("linkLabel",
-                            subItem.getName())));
+                    protected void populateItem(ListItem<Link<Page>> item) {
+                        item.add(item.getModelObject());
                     }
                 });
             }
@@ -64,32 +52,4 @@
 
     }
 
-    private static class SimplifiedModel implements Serializable {
-
-        private String name;
-        private Class<? extends Page> clazz;
-
-        public SimplifiedModel(String name, Class<? extends Page> clazz) {
-            this.name = name;
-            this.clazz = clazz;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-
-        public Class<? extends Page> getClazz() {
-            return clazz;
-        }
-
-        public void setClazz(Class<? extends Page> clazz) {
-            this.clazz = clazz;
-        }
-
-    }
-
 }
diff --git a/core/src/main/resources/OSGI-INF/blueprint/core.xml b/core/src/main/resources/OSGI-INF/blueprint/core.xml
index 602dba7..b2d5ac9 100644
--- a/core/src/main/resources/OSGI-INF/blueprint/core.xml
+++ b/core/src/main/resources/OSGI-INF/blueprint/core.xml
@@ -21,18 +21,14 @@
         class="org.apache.karaf.webconsole.core.internal.WebConsoleApplication"
         applicationName="karafWebConsole" mountPoint="cns" />
 
-    <reference-list id="tabs" interface="org.apache.karaf.webconsole.core.navigation.ConsoleTab" availability="optional" />
+    <reference-list id="tabs" interface="org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider" availability="optional" />
 
     <!-- He is not ready yet ... -->
     <reference-list id="widgets" interface="org.apache.karaf.webconsole.core.widget.WidgetProvider" availability="optional"
         filter="(intention=dashboard)" />
 
-    <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTab">
-        <bean class="org.apache.karaf.webconsole.core.navigation.i18n.LocalizableConsoleTab">
-            <argument>
-                <bean class="org.apache.karaf.webconsole.core.internal.SystemConsoleTab" />
-            </argument>
-        </bean>
+    <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider">
+        <bean class="org.apache.karaf.webconsole.core.internal.SystemConsoleTabProvider" />
     </service>
 
     <service interface="org.apache.karaf.webconsole.core.brand.BrandProvider">
diff --git a/core/src/main/resources/org/apache/karaf/webconsole/core/BasePage2.html b/core/src/main/resources/org/apache/karaf/webconsole/core/BasePage2.html
deleted file mode 100644
index 0d0c2d1..0000000
--- a/core/src/main/resources/org/apache/karaf/webconsole/core/BasePage2.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
-
-<head>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <title>Karaf WebConsole</title>
-</head>
-
-<body>
-    <div id="container">
-        <table>
-            <tr>
-                <td align="left"><img wicket:id="karafLogo" alt="karaf-logo" height="70" width="150"/></td>
-                <td align="right">Administration console</td>
-            </tr>
-            <!--
-            <tr>
-            <div wicket:id="navigationPanel">Navigation goes here</div>
-            <div wicket:id="sidebar">Sidebar goes here</div>
-            </tr>
-            -->
-            <tr>
-                <td colspan="2">
-                    <div wicket:id="tabPanels" class="tabpanel">[tabbed panel will be here]</div>
-
-                    <div id="topmenu">
-                        <ul>
-                            <li wicket:id="tabs">
-                                <a wicket:id="moduleLink">
-                                    <span wicket:id="moduleLabel">Category</span>
-                                </a>
-
-                                <ul>
-                                    <li wicket:id="topLinks">
-                                        <a wicket:id="topLink">
-                                            <span wicket:id="linkLabel">Label</span>
-                                        </a>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </div>
-                </td>
-            </tr>
-            <tr>
-                <td colspan="2">
-                    <div id="content">
-                        <wicket:child/>
-                    </div>
-                </td>
-            </tr>
-            <tr>
-                <td colspan="2">&nbsp</td>
-            </tr>
-            <tr>
-                <td colspan="2">
-                    <div id="footer" align="right">
-                        <div wicket:id="footer">Footer</div>
-                    </div>
-                 </td>
-            </tr>
-        </table>
-    </div>
-</body>
-</html>
\ No newline at end of file
diff --git a/core/src/main/resources/org/apache/karaf/webconsole/core/navigation/markup/NavigationPanel.html b/core/src/main/resources/org/apache/karaf/webconsole/core/navigation/markup/NavigationPanel.html
index e855dba..18d33c2 100644
--- a/core/src/main/resources/org/apache/karaf/webconsole/core/navigation/markup/NavigationPanel.html
+++ b/core/src/main/resources/org/apache/karaf/webconsole/core/navigation/markup/NavigationPanel.html
@@ -31,9 +31,9 @@
                     </a>
 
                     <ul>
-                        <li wicket:id="topLinks">
-                            <a wicket:id="topLink">
-                                <span wicket:id="linkLabel">Label</span>
+                        <li wicket:id="moduleLinks">
+                            <a wicket:id="link">
+                                <span wicket:id="label">Label</span>
                             </a>
                         </li>
                     </ul>
diff --git a/karaf/src/main/java/org/apache/karaf/webconsole/karaf/internal/navigation/KarafConsoleTab.java b/karaf/src/main/java/org/apache/karaf/webconsole/karaf/internal/navigation/KarafConsoleTab.java
deleted file mode 100644
index 60c617e..0000000
--- a/karaf/src/main/java/org/apache/karaf/webconsole/karaf/internal/navigation/KarafConsoleTab.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.webconsole.karaf.internal.navigation;
-
-import org.apache.karaf.webconsole.core.navigation.ConsoleTab;
-import org.apache.karaf.webconsole.karaf.internal.feature.FeaturesPage;
-import org.apache.karaf.webconsole.karaf.internal.repository.RepositoriesPage;
-import org.apache.wicket.Page;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class KarafConsoleTab implements ConsoleTab {
-
-    public String getLabel() {
-        return "karaf";
-    }
-
-    public Class<? extends Page> getModuleHomePage() {
-        return FeaturesPage.class;
-    }
-
-    public Map<String, Class<? extends Page>> getItems() {
-        Map<String, Class<? extends Page>> features = new HashMap<String, Class<? extends Page>>();
-        features.put("Repositories list", RepositoriesPage.class);
-        features.put("Features list", FeaturesPage.class);
-        return features;
-    }
-
-}
diff --git a/karaf/src/main/java/org/apache/karaf/webconsole/karaf/internal/navigation/KarafConsoleTabProvider.java b/karaf/src/main/java/org/apache/karaf/webconsole/karaf/internal/navigation/KarafConsoleTabProvider.java
new file mode 100644
index 0000000..05b4c99
--- /dev/null
+++ b/karaf/src/main/java/org/apache/karaf/webconsole/karaf/internal/navigation/KarafConsoleTabProvider.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.webconsole.karaf.internal.navigation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider;
+import org.apache.karaf.webconsole.karaf.internal.feature.FeaturesPage;
+import org.apache.karaf.webconsole.karaf.internal.repository.RepositoriesPage;
+import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.link.Link;
+
+public class KarafConsoleTabProvider implements ConsoleTabProvider {
+
+    public Link<Page> getModuleLink(String componentId, String labelId) {
+        return createFeaturesLink(componentId, labelId);
+    }
+
+    public List<Link<Page>> getItems(String componentId, String labelId) {
+        List<Link<Page>> items = new ArrayList<Link<Page>>();
+
+        Link<Page> link = createFeaturesLink(componentId, labelId);
+
+        link = new BookmarkablePageLink<Page>(componentId, RepositoriesPage.class);
+        link.add(new Label(labelId, "Repositories"));
+        items.add(link);
+
+        return items;
+    }
+
+    private Link<Page> createFeaturesLink(String componentId, String labelId) {
+        Link<Page> link = new BookmarkablePageLink<Page>(componentId, FeaturesPage.class);
+        link.add(new Label(labelId, "Features"));
+
+        return link;
+    }
+
+}
diff --git a/karaf/src/main/resources/OSGI-INF/blueprint/karaf.xml b/karaf/src/main/resources/OSGI-INF/blueprint/karaf.xml
index 315edcf..9468270 100644
--- a/karaf/src/main/resources/OSGI-INF/blueprint/karaf.xml
+++ b/karaf/src/main/resources/OSGI-INF/blueprint/karaf.xml
@@ -17,8 +17,8 @@
 -->
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
 
-    <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTab">
-        <bean class="org.apache.karaf.webconsole.karaf.internal.navigation.KarafConsoleTab" />
+    <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider">
+        <bean class="org.apache.karaf.webconsole.karaf.internal.navigation.KarafConsoleTabProvider" />
     </service>
 
     <reference id="featuresService" interface="org.apache.karaf.features.FeaturesService"/>
diff --git a/osgi/src/main/java/org/apache/karaf/webconsole/osgi/internal/navigation/OsgiConsoleTab.java b/osgi/src/main/java/org/apache/karaf/webconsole/osgi/internal/navigation/OsgiConsoleTab.java
deleted file mode 100644
index 1aa858d..0000000
--- a/osgi/src/main/java/org/apache/karaf/webconsole/osgi/internal/navigation/OsgiConsoleTab.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.webconsole.osgi.internal.navigation;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.karaf.webconsole.core.navigation.ConsoleTab;
-import org.apache.karaf.webconsole.osgi.internal.bundle.BundlesPage;
-import org.apache.wicket.Page;
-
-public class OsgiConsoleTab implements ConsoleTab {
-
-    public String getLabel() {
-        return "osgi";
-    }
-
-    public Class<? extends Page> getModuleHomePage() {
-        return BundlesPage.class;
-    }
-
-    public Map<String, Class<? extends Page>> getItems() {
-        return new HashMap<String, Class<? extends Page>>();
-    }
-
-}
diff --git a/osgi/src/main/java/org/apache/karaf/webconsole/osgi/internal/navigation/OsgiConsoleTabProvider.java b/osgi/src/main/java/org/apache/karaf/webconsole/osgi/internal/navigation/OsgiConsoleTabProvider.java
new file mode 100644
index 0000000..f93c404
--- /dev/null
+++ b/osgi/src/main/java/org/apache/karaf/webconsole/osgi/internal/navigation/OsgiConsoleTabProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.webconsole.osgi.internal.navigation;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider;
+import org.apache.karaf.webconsole.osgi.internal.bundle.BundlesPage;
+import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.link.Link;
+
+public class OsgiConsoleTabProvider implements ConsoleTabProvider {
+
+    public Link<Page> getModuleLink(String componentId, String labelId) {
+        Link<Page> link = new BookmarkablePageLink<Page>(componentId, BundlesPage.class);
+        link.add(new Label(labelId, "Bundles"));
+        return link;
+    }
+
+    public List<Link<Page>> getItems(String componentId, String labelId) {
+        return Collections.emptyList();
+    }
+
+}
diff --git a/osgi/src/main/resources/OSGI-INF/blueprint/osgi.xml b/osgi/src/main/resources/OSGI-INF/blueprint/osgi.xml
index fa2064d..9ca6654 100644
--- a/osgi/src/main/resources/OSGI-INF/blueprint/osgi.xml
+++ b/osgi/src/main/resources/OSGI-INF/blueprint/osgi.xml
@@ -22,14 +22,10 @@
         http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
     ">
 
-    <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTab">
-        <bean class="org.apache.karaf.webconsole.core.navigation.ExtendableConsoleTab">
+    <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider">
+        <bean class="org.apache.karaf.webconsole.core.navigation.ExtendableConsoleTabProvider">
             <argument>
-                <bean class="org.apache.karaf.webconsole.core.navigation.i18n.LocalizableConsoleTab">
-                    <argument>
-                        <bean class="org.apache.karaf.webconsole.osgi.internal.navigation.OsgiConsoleTab" />
-                    </argument>
-                </bean>
+                <bean class="org.apache.karaf.webconsole.osgi.internal.navigation.OsgiConsoleTabProvider" />
             </argument>
             <property name="extensions">
                 <reference-list interface="org.apache.karaf.webconsole.core.navigation.NavigationProvider"
diff --git a/servicemix/src/main/java/org/apache/karaf/webconsole/servicemix/internal/navigation/ServiceMixConsoleTab.java b/servicemix/src/main/java/org/apache/karaf/webconsole/servicemix/internal/navigation/ServiceMixConsoleTab.java
deleted file mode 100644
index 62de714..0000000
--- a/servicemix/src/main/java/org/apache/karaf/webconsole/servicemix/internal/navigation/ServiceMixConsoleTab.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.apache.karaf.webconsole.servicemix.internal.navigation;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.karaf.webconsole.core.navigation.ConsoleTab;
-import org.apache.karaf.webconsole.servicemix.internal.ServiceMixPage;
-import org.apache.wicket.Page;
-
-public class ServiceMixConsoleTab implements ConsoleTab {
-
-    public Map<String, Class<? extends Page>> getItems() {
-        return Collections.emptyMap();
-    }
-
-    public String getLabel() {
-        return "servicemix";
-    }
-
-    public Class<? extends Page> getModuleHomePage() {
-        return ServiceMixPage.class;
-    }
-
-  
-
-}
diff --git a/servicemix/src/main/java/org/apache/karaf/webconsole/servicemix/internal/navigation/ServiceMixConsoleTabProvider.java b/servicemix/src/main/java/org/apache/karaf/webconsole/servicemix/internal/navigation/ServiceMixConsoleTabProvider.java
new file mode 100644
index 0000000..925be9b
--- /dev/null
+++ b/servicemix/src/main/java/org/apache/karaf/webconsole/servicemix/internal/navigation/ServiceMixConsoleTabProvider.java
@@ -0,0 +1,27 @@
+package org.apache.karaf.webconsole.servicemix.internal.navigation;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider;
+import org.apache.karaf.webconsole.servicemix.internal.ServiceMixPage;
+import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.link.Link;
+
+public class ServiceMixConsoleTabProvider implements ConsoleTabProvider {
+
+    public List<Link<Page>> getItems(String componentId, String labelId) {
+        return Collections.emptyList();
+    }
+
+    public Link<Page> getModuleLink(String componentId, String labelId) {
+        Link<Page> link = new BookmarkablePageLink<Page>(componentId, ServiceMixPage.class);
+        link.add(new Label(labelId, "ServiceMix"));
+        return link;
+    }
+
+  
+
+}
diff --git a/servicemix/src/main/resources/OSGI-INF/blueprint/servicemix.xml b/servicemix/src/main/resources/OSGI-INF/blueprint/servicemix.xml
index fa33eb2..a83afdf 100644
--- a/servicemix/src/main/resources/OSGI-INF/blueprint/servicemix.xml
+++ b/servicemix/src/main/resources/OSGI-INF/blueprint/servicemix.xml
@@ -17,8 +17,8 @@
 -->
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
 
-    <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTab">
-        <bean class="org.apache.karaf.webconsole.servicemix.internal.navigation.ServiceMixConsoleTab" />
+    <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider">
+        <bean class="org.apache.karaf.webconsole.servicemix.internal.navigation.ServiceMixConsoleTabProvider" />
     </service>
 
     <reference id="nmr" interface="org.apache.servicemix.nmr.api.NMR"/>