diff --git a/ipojo/webconsole-plugin/metadata.xml b/ipojo/webconsole-plugin/metadata.xml
deleted file mode 100644
index dd6fa0d..0000000
--- a/ipojo/webconsole-plugin/metadata.xml
+++ /dev/null
@@ -1,21 +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.
--->
-<ipojo>
-  <instance component="org.apache.felix.ipojo.webconsole.IPOJOServlet"/>
-</ipojo>
diff --git a/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOServlet.java b/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOServlet.java
deleted file mode 100644
index 2f6c2dc..0000000
--- a/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOServlet.java
+++ /dev/null
@@ -1,846 +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.felix.ipojo.webconsole;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-
-import javax.servlet.Servlet;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.Factory;
-import org.apache.felix.ipojo.HandlerFactory;
-import org.apache.felix.ipojo.annotations.Component;
-import org.apache.felix.ipojo.annotations.Invalidate;
-import org.apache.felix.ipojo.annotations.Provides;
-import org.apache.felix.ipojo.annotations.Requires;
-import org.apache.felix.ipojo.annotations.ServiceProperty;
-import org.apache.felix.ipojo.architecture.Architecture;
-import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.architecture.InstanceDescription;
-import org.apache.felix.ipojo.architecture.PropertyDescription;
-import org.apache.felix.ipojo.handlers.dependency.DependencyDescription;
-import org.apache.felix.ipojo.handlers.dependency.DependencyHandlerDescription;
-import org.apache.felix.ipojo.handlers.providedservice.ProvidedService;
-import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceDescription;
-import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandlerDescription;
-import org.apache.felix.ipojo.util.DependencyModel;
-import org.apache.felix.webconsole.AbstractWebConsolePlugin;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-/**
- * iPOJO Plugin for the web console.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-@Component(immediate = true)
-@Provides(specifications = { Servlet.class })
-public class IPOJOServlet extends AbstractWebConsolePlugin {
-
-    /**
-     * Factory constant.
-     */
-    public static final String FACTORY = "factory";
-
-    /**
-     * Instance constant.
-     */
-    public static final String INSTANCE = "instance";
-
-    /**
-     * Handler constant.
-     */
-    public static final String HANDLER = "handler";
-
-    /**
-     * All constant.
-     */
-    public static final String ALL = "all";
-
-    /**
-     * UUID.
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Label used by the web console.
-     */
-    @ServiceProperty(name = "felix.webconsole.label")
-    private String m_label = "iPOJO";
-
-    /**
-     * Title used by the web console.
-     */
-    @ServiceProperty(name = "felix.webconsole.title")
-    private String m_title = "iPOJO";
-
-    /**
-     * List of available Architecture service.
-     */
-    @Requires(optional = true, specification = "org.apache.felix.ipojo.architecture.Architecture")
-    private List<Architecture> m_archs;
-
-    /**
-     * List of available Factories.
-     */
-    @Requires(optional = true, specification = "org.apache.felix.ipojo.Factory")
-    private List<Factory> m_factories;
-
-    /**
-     * List of available Handler Factories.
-     */
-    @Requires(optional = true, specification = "org.apache.felix.ipojo.HandlerFactory")
-    private List<HandlerFactory> m_handlers;
-
-    /**
-     * Creates a IPOJOServlet.
-     * This method activates the plugin.
-     * @param bc the bundle context
-     */
-    public IPOJOServlet(BundleContext bc) {
-        activate(bc);
-    }
-
-    /**
-     * Stop method.
-     * This method deactivates the plugin.
-     */
-    @Invalidate
-    public void stop() {
-        deactivate();
-    }
-
-
-    /**
-     * Gets the plugin label.
-     * @return the label
-     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#getLabel()
-     */
-    public String getLabel() {
-        return m_label;
-    }
-
-    /**
-     * Gets the plugin title.
-     * @return the title
-     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#getTitle()
-     */
-    public String getTitle() {
-        return m_title;
-    }
-
-    /**
-     * Gets the number of valid instances.
-     * @return the number of valid instances.
-     */
-    private int getValidCount() {
-        int i = 0;
-        for (Architecture a : m_archs) { // Cannot be null, an empty list is returned.
-            if (a.getInstanceDescription().getState() == ComponentInstance.VALID) {
-                i ++;
-            }
-        }
-        return i;
-    }
-
-    /**
-     * Gets the number of invalid instances.
-     * @return the number of invalid instances.
-     */
-    private int getInvalidCount() {
-        int i = 0;
-        for (Architecture a : m_archs) {  // Cannot be null, an empty list is returned.
-            if (a.getInstanceDescription().getState() == ComponentInstance.INVALID) {
-                i ++;
-            }
-        }
-        return i;
-    }
-
-    /**
-     * Gets the HTML content of the plugin.
-     * @param req the request
-     * @param res the response
-     * @throws ServletException if the content cannot be computed
-     * @throws IOException if an IO Exception occurs
-     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
-     */
-    protected void renderContent(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
-
-        PrintWriter writer = res.getWriter();
-        // Set the fable plugin_table sortable.
-        writer.write("<script type=\"text/javascript\"> "
-                 + "function setSortable() { \n"
-                 + "$(document).ready(function() { \n"
-                 + "$(\"#plugin_table\").tablesorter(); \n"
-                 + "})};\n"
-                 + "setSortable();"
-                 + "</script>");
-        // Status Line
-        writer.write("<div class=\"fullwidth\"><div class=\"statusline\">"
-                + m_archs.size() + " instances in total, "
-                + getValidCount() + " valid instances, "
-                + getInvalidCount() + " invalid instances."
-                +        "</div></div>");
-        // Button Line
-        writer.write("<form action=\"iPOJO\" method=\"get\">"
-                + "<div class=\"fullwidth\">"
-                + "<div class=\"buttons\">"
-                + "<button style=\"margin-left: 30px;\" name=\"" + INSTANCE + "\" value=\"all\" type=\"submit\">Instances</button>"
-                + "<button style=\"margin-left: 30px;\" name=\"" + FACTORY + "\" value=\"all\" type=\"submit\">Factories</button>"
-                + "<button style=\"margin-left: 30px;\" name=\"" + HANDLER + "\" value=\"all\" type=\"submit\">Handlers</button>"
-                + "</div>"
-                + "</div>"
-                + "</form>");
-
-        // Compute the request and select the content to return
-        RequestInfo ri = new RequestInfo(req);
-        if (ri.m_type.equals(FACTORY)) {
-            if (ri.m_all) {
-                printFactoryList(writer);
-            } else {
-                printFactoryDetail(writer, ri.m_name);
-            }
-        }
-
-        if (ri.m_type.equals(INSTANCE)) {
-            if (ri.m_all) {
-                printInstanceList(writer);
-            } else {
-                printInstanceDetail(writer, ri.m_name);
-            }
-        }
-
-        if (ri.m_type.equals(HANDLER)) {
-            if (ri.m_all) {
-                printHandlerList(writer);
-            }
-        }
-
-        // Button Line
-        writer.write("<form action=\"iPOJO\" method=\"get\">"
-                + "<div class=\"fullwidth\">"
-                + "<div class=\"buttons\">"
-                + "<button style=\"margin-left: 30px;\" name=\"" + INSTANCE + "\" value=\"all\" type=\"submit\">Instances</button>"
-                + "<button style=\"margin-left: 30px;\" name=\"" + FACTORY + "\" value=\"all\" type=\"submit\">Factories</button>"
-                + "<button style=\"margin-left: 30px;\" name=\"" + HANDLER + "\" value=\"all\" type=\"submit\">Handlers</button>"
-                + "</div>"
-                + "</div>"
-                + "</form>");
-
-        // Status Line
-        writer.write("<div class=\"fullwidth\"><div class=\"statusline\">"
-                + m_archs.size() + " instances in total, "
-                + getValidCount() + " valid instances, "
-                + getInvalidCount() + " invalid instances."
-                +        "</div></div>");
-
-    }
-
-    /**
-     * Gets a Factory Detail page.
-     * This page contains all versions of the factories.
-     * @param pw the writer
-     * @param name the name of the factory
-     */
-    private void printFactoryDetail(PrintWriter pw, String name) {
-        List<ComponentTypeDescription> fs = new ArrayList<ComponentTypeDescription>();
-        for (Factory f : this.m_factories) { // Cannot be null, an empty list is returned.
-            if (f.getName().equals(name)) {
-                fs.add(f.getComponentDescription());
-            }
-        }
-
-        pw.write("<div class=\"table\">");
-        if (fs.isEmpty()) {
-            pw.write("<b>Factory not found</b><br>The factory " + name + " does not exist or is private");
-        } else {
-            for (ComponentTypeDescription factory : fs) {
-                pw.write("<table class=\"tablelayout\" border=\"0\"><tbody>");
-                addEntry(pw, "Factory Name", factory.getName());
-                if (factory.getVersion() != null) {
-                    addEntry(pw, "Factory Version", factory.getVersion());
-                }
-                addEntry(pw, "State", getFactoryState(factory.getFactory().getState()));
-
-                addEntry(pw, " ", " ");
-                if (factory.getprovidedServiceSpecification() != null && factory.getprovidedServiceSpecification().length != 0) {
-                    addEntry(pw, "Provided Service Specification", Arrays.toString(factory.getprovidedServiceSpecification()));
-                }
-                if (factory.getProperties() != null && factory.getProperties().length != 0) {
-                    addEntry(pw, "Properties", getProperties(factory.getProperties()));
-                }
-
-                addEntry(pw, " ", " ");
-                addEntry(pw, "Required Handlers", factory.getFactory().getRequiredHandlers().toString());
-                addEntry(pw, "Missing Handlers", factory.getFactory().getMissingHandlers().toString());
-                addEntry(pw, " ", " ");
-                addEntry(pw, "Created Instances", getInstanceList(factory.getName()));
-
-                addEntry(pw, " ", " ");
-                addEntry(pw, "Architecture",
-                        "<div style=\"overflow: auto; width:800px; border: 1px solid #666; background-color: #ccc; padding: 8px;\"><pre>"
-                            + factory.getDescription().toString()
-                            + "</pre></div>");
-                pw.write("</tbody></table>");
-            }
-        }
-        pw.write("</div>");
-    }
-
-
-    /**
-     * Gets component type properties HTML table.
-     * @param properties the properties to display
-     * @return the HTML code of the table
-     */
-    private String getProperties(PropertyDescription[] properties) {
-        String s = "<table class=\"tablelayout\" style=\"border-top: 1px solid #6181A9;\">"
-                + "<thead style=\"border-top: 1px solid #6181A9;\">"
-                + "<tr>"
-                + "<th>Property Name</th>"
-                + "<th>Property Type</th>"
-                + "<th>Mandatory</th>"
-                + "<th>Immutable</th>"
-                + "<th>Value</th>"
-                + "</tr>"
-                + "</thead>"
-                + "<tbody>";
-        if (properties != null) {
-            for (PropertyDescription pd : properties) {
-                String name = pd.getName();
-                String type = pd.getType();
-                boolean mandatory = pd.isMandatory();
-                boolean immutable = pd.isImmutable();
-                String value = pd.getValue();
-                s += "<tr>" + "<td>" + name + "</td>" + "<td>" + type + "</td>"
-                        + "<td>" + "" + mandatory + "</td>" + "<td>" + ""
-                        + immutable + "</td>" + "<td>"
-                        + (value == null ? "<i>No Value</i>" : value) + "</td>"
-                        + "</tr>";
-            }
-        }  // Else don't print anything.
-        s += "</tbody></table>";
-        return s;
-    }
-
-    /**
-     * Gets the instance list page.
-     * @param pw the writer
-     */
-    private void printInstanceList(PrintWriter pw) {
-        pw.write("<div class=\"table\">"
-                + "<table id=\"plugin_table\" class=\"tablelayout\">"
-                + "<thead>"
-                + "<tr>"
-                + "<th class=\"col_Name header headerSortDown\">Instance Name</th>"
-                + "<th class=\"col_Factory header \">Factory Name</th>"
-                + "<th class=\"col_State header \">State</th>"
-                + "</tr>"
-                + "</thead>"
-                + "<tbody>");
-
-        for (Architecture arch : m_archs) { // Cannot be null, an empty list is returned.
-            InstanceDescription id = arch.getInstanceDescription();
-            String name = id.getName();
-            String factory = id.getComponentDescription().getName();
-            String state = getInstanceState(id.getState());
-
-            pw.write("<tr>"
-                    + "<td>" + getInstanceLink(name) + "</td>"
-                    + "<td>" + factory + "</td>"
-                    + "<td>" + state + "</td>"
-                    + "</tr>");
-
-        }
-
-        pw.write("</tbody></table>");
-    }
-
-    /**
-     * Adds a line into a key / value table.
-     * @param pw the writer
-     * @param header the key
-     * @param value the value (may be HTML code)
-     */
-    private void addEntry(PrintWriter pw, String header, String value) {
-        pw.write(addEntry(header, value));
-
-    }
-
-    /**
-     * Gets the HTML code of a key / value table row.
-     * @param header the key
-     * @param value the value (may be HTML code)
-     * @return the HTML code of the line
-     */
-    private String addEntry(String header, String value) {
-        return "<tr>"
-                + "<td class=\"aligntop\" nowrap=\"true\" style=\"border: 0px none;\">" + header + "</td>"
-                + "<td class=\"aligntop\" style=\"border: 0px none ;\">" + value + "</td>"
-                + "</tr>";
-    }
-
-    /**
-     * Gets the factory link if the factory exists.
-     * @param id the factory name
-     * @return the HTML link targetting the detail of the factory or just the factory name.
-     */
-    private String getFactoryLinkIfPossible(InstanceDescription id) {
-        String n = id.getComponentDescription().getName();
-        for (Factory f : m_factories) { // Cannot be null, an empty list is returned.
-            if (f.getName().equals(n)) {
-                return "<a href=\"iPOJO?factory=" + n + "\">" + n + "</a>";
-            }
-        }
-
-        return n; // No link
-    }
-
-    /**
-     * Gets the list of invalid handler.
-     * @param hl the handler description list.
-     * @return the list of invalid handlers.
-     */
-    private String getInvalidHandlerList(HandlerDescription[] hl) {
-        List<String> list = new ArrayList<String>();
-        if (hl != null) {
-            for (HandlerDescription hd : hl) {
-                if (! hd.isValid()) {
-                    list.add(hd.getHandlerName());
-                }
-            }
-        }
-        return list.toString();
-    }
-
-    /**
-     * Gets the page containing instance detail.
-     * @param pw the writer
-     * @param name the instance name
-     */
-    private void printInstanceDetail(PrintWriter pw, String name) {
-        InstanceDescription desc = getInstanceDescriptionByName(name);
-        pw.write("<div class=\"table\">");
-        if (desc == null) {
-            pw.write("<b>Instance not found</b><br>The instance " + name + " does not exist or does not expose its architecture");
-        } else {
-            pw.write("<table class=\"tablelayout\" border=\"0\"><tbody>");
-            addEntry(pw, "Instance Name", desc.getName());
-            addEntry(pw, "Factory", getFactoryLinkIfPossible(desc));
-            if (desc.getState() == ComponentInstance.INVALID) {
-                addEntry(pw, "Invalid Handlers", getInvalidHandlerList(desc.getHandlers()));
-            }
-            addEntry(pw, " ", " ");
-            addEntry(pw, "Provided Services", getProvidedServiceDetail(desc.getHandlerDescription("org.apache.felix.ipojo:provides")));
-            addEntry(pw, "Required Services", getRequiredServiceDetail(desc.getHandlerDescription("org.apache.felix.ipojo:requires")));
-
-            addEntry(pw, " ", " ");
-            addEntry(pw, "Architecture",
-                    "<div style=\"overflow: auto; width:800px; border: 1px solid #666; background-color: #ccc; padding: 8px;\"><pre>"
-                        + desc.getDescription().toString()
-                        + "</pre></div>");
-            pw.write("</tbody></table>");
-        }
-        pw.write("</div>");
-    }
-
-    /**
-     * Gets the HTML link targeting this instance.
-     * @param name the instance name
-     * @return the HTML link targetting the instance detail
-     */
-    private String getInstanceLink(String name) {
-        return "<a href=\"iPOJO?instance=" + name + "\">" + name + "</a>";
-    }
-
-    /**
-     * Gets the HTML list of service properties.
-     * @param properties the properties
-     * @return the HTML code containing the service properties.
-     */
-    private String getServiceProperties(Properties properties) {
-        String s = "<ul>";
-        Enumeration<Object> e = properties.keys();
-        while (e.hasMoreElements()) {
-            String key = (String) e.nextElement();
-            String value = properties.get(key).toString();
-            s += "<li>" + key + " = " + value + "</li>";
-        }
-        s += "</ul>";
-        return s;
-    }
-
-    /**
-     * Gets the instance list created by the given factory.
-     * @param factory the factory name
-     * @return the HTML list containing the created instances
-     */
-    private String getInstanceList(String factory) {
-        String s = "<ul>";
-        for (Architecture arch : m_archs) { // Cannot be null, an empty list is returned.
-            String n = arch.getInstanceDescription().getComponentDescription().getName();
-            if (factory.equals(n)) {
-                s += "<li>" + getInstanceLink(arch.getInstanceDescription().getName()) + "</li>";
-            }
-        }
-        s += "</ul>";
-        return s;
-    }
-
-    /**
-     * Gets the HTML list containing service references.
-     * If the service is provided by an iPOJO instance, the link is inserted.
-     * @param refs the references.
-     * @return the HTML list
-     */
-    private String getServiceReferenceList(List<ServiceReference> refs) {
-        String s = "<ul>";
-        if (refs != null) {
-            for (ServiceReference ref : refs) {
-                s += "<li>";
-                if (ref.getProperty("instance.name") == null) {
-                    s += ref.getProperty(Constants.SERVICE_ID);
-                } else {
-                    s += "<a href=\"iPOJO?instance="
-                        + ref.getProperty("instance.name") + "\">"
-                        + ref.getProperty("instance.name") + " (" +  ref.getProperty(Constants.SERVICE_ID) + ")</a>";
-                }
-                s += "</li>";
-            }
-        }
-        s += "</ul>";
-        return s;
-    }
-
-    /**
-     * Gets provided service details.
-     * @param hd the provided service handler description or <code>null</code> if not found.
-     * @return the details about provided services
-     */
-    private String getProvidedServiceDetail(HandlerDescription hd) {
-        if (hd == null) {
-            return "No provided services";
-        }
-
-        String r = "";
-        ProvidedServiceHandlerDescription desc = (ProvidedServiceHandlerDescription) hd;
-
-        for (ProvidedServiceDescription ps : desc.getProvidedServices()) {
-            r += "<table border=\"0\"><tbody>";
-            r += addEntry("Specification", Arrays.toString(ps.getServiceSpecifications()));
-            r += addEntry("State", getProvidedServiceState(ps.getState()));
-            if (ps.getServiceReference() != null) {
-                r += addEntry("Service Id", ((Long) ps.getServiceReference().getProperty(Constants.SERVICE_ID)).toString());
-            }
-            r += addEntry("Service Properties", getServiceProperties(ps.getProperties()));
-
-            r += "</tbody></table>";
-            r += "<hr style=\"color: #CCCCCC;'\"/>";
-        }
-
-        return r;
-
-    }
-
-    /**
-     * Gets required service details.
-     * @param hd the required service handler description or <code>null</code> if not found.
-     * @return the details about required services
-     */
-    private String getRequiredServiceDetail(
-            HandlerDescription hd) {
-        if (hd == null) {
-            return "No required services";
-        }
-        String r = "";
-        DependencyHandlerDescription desc = (DependencyHandlerDescription) hd;
-        for (DependencyDescription dep : desc.getDependencies()) {
-            r += "<table border=\"0\" style=\"margin-bottom:5px\"><tbody>";
-            r += addEntry("Specification", dep.getSpecification());
-            r += addEntry("Id", "" + dep.getId());
-            r += addEntry("State", getDependencyState(dep.getState()));
-            r += addEntry("Binding Policy" , getDependencyBindingPolicy(dep.getPolicy()));
-            r += addEntry("Optional", "" + dep.isOptional());
-            r += addEntry("Aggregate", "" + dep.isMultiple());
-            if (dep.getFilter() != null) {
-                r += addEntry("Filter", "" + dep.getFilter());
-            }
-            if (dep.getComparator() != null) {
-                r += addEntry("Comparator", "" + dep.getComparator());
-            }
-            r += addEntry("Matching Services", getServiceReferenceList(dep.getServiceReferences()));
-            r += addEntry("Used Services", getServiceReferenceList(dep.getUsedServices()));
-
-            r += "</tbody></table>";
-            r += "<hr style=\"color: #CCCCCC;'\"/>";
-
-        }
-
-        return r;
-    }
-
-    /**
-     * Gets the instance description by name.
-     * @param name the instance name
-     * @return the instance description or <code>null</code> if not found
-     */
-    private InstanceDescription getInstanceDescriptionByName(String name) {
-        for (Architecture arch : m_archs) { 
-            if (name.equals(arch.getInstanceDescription().getName())) {
-                return arch.getInstanceDescription();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Prints the factory list.
-     * @param pw the writer.
-     */
-    private void printFactoryList(PrintWriter pw) {
-        pw.write("<div class=\"table\">"
-                + "<table id=\"plugin_table\" class=\"tablelayout\">"
-                + "<thead>"
-                + "<tr>"
-                + "<th class=\"col_Name header headerSortDown\">Factory Name</th>"
-                + "<th class=\"col_Bundle header \">Bundle</th>"
-                + "<th class=\"col_State header \">State</th>"
-                + "</tr>"
-                + "</thead>"
-                + "<tbody>");
-
-
-
-        for (Factory factory : m_factories) {
-            String name = factory.getName();
-            String version = factory.getVersion();
-            String state = getFactoryState(factory.getState());
-            String bundle = factory.getBundleContext().getBundle().getSymbolicName()
-                + " (" + factory.getBundleContext().getBundle().getBundleId() + ")";
-            pw.write("<tr>"
-                    + "<td><a href=\"iPOJO?factory=" + name + "\">"
-                        + (version == null ? name : name + " (" + version + ")")
-                        + "</a></td>"
-                    + "<td>" + bundle + "</td>"
-                    + "<td>" + state + "</td>"
-                    + "</tr>");
-
-        }
-
-        pw.write("</tbody></table>");
-    }
-
-    /**
-     * Print the handler list.
-     * @param pw the writer.
-     */
-    private void printHandlerList(PrintWriter pw) {
-        pw.write("<div class=\"table\">"
-                + "<table id=\"plugin_table\" class=\"tablelayout\">"
-                + "<thead>"
-                + "<tr>"
-                + "<th class=\"col_Name header headerSortDown\">Handler Name</th>"
-                + "<th class=\"col_Type header \">Handler Type</th>"
-                + "<th class=\"col_Bundle header \">Bundle</th>"
-                + "<th class=\"col_State header \">State</th>"
-                + "<th class=\"col_MissingHandler header \">Missing Handler</th>"
-                + "</tr>"
-                + "</thead>"
-                + "<tbody>");
-
-
-
-        for (HandlerFactory hf : m_handlers) {
-            String name = hf.getHandlerName();
-            String type = hf.getType();
-            String state = getFactoryState(hf.getState());
-            String bundle = hf.getBundleContext().getBundle().getSymbolicName()
-                + " (" + hf.getBundleContext().getBundle().getBundleId() + ")";
-            String missing = hf.getMissingHandlers().isEmpty() ? "<i>no missing handlers</i>" : hf.getMissingHandlers().toString();
-            pw.write("<tr>"
-                    + "<td>" + name + "</td>"
-                    + "<td>" + type + "</td>"
-                    + "<td>" + bundle + "</td>"
-                    + "<td>" + state + "</td>"
-                    + "<td>" + missing + "</td>"
-                    + "</tr>");
-
-        }
-
-        pw.write("</tbody></table>");
-    }
-
-    /**
-     * Gets the instance state as a String.
-     * @param state the state.
-     * @return the String form of the state.
-     */
-    private static String getInstanceState(int state) {
-        switch(state) {
-            case ComponentInstance.VALID :
-                return "valid";
-            case ComponentInstance.INVALID :
-                return "invalid";
-            case ComponentInstance.DISPOSED :
-                return "disposed";
-            case ComponentInstance.STOPPED :
-                return "stopped";
-            default :
-                return "unknown";
-        }
-    }
-
-    /**
-     * Gets the factory state as a String.
-     * @param state the state.
-     * @return the String form of the state.
-     */
-    private static String getFactoryState(int state) {
-        switch(state) {
-            case Factory.VALID :
-                return "valid";
-            case Factory.INVALID :
-                return "invalid";
-            default :
-                return "unknown";
-        }
-    }
-
-    /**
-     * Gets the dependency state as a String.
-     * @param state the state.
-     * @return the String form of the state.
-     */
-    private static String getDependencyState(int state) {
-        switch(state) {
-            case DependencyModel.RESOLVED :
-                return "resolved";
-            case DependencyModel.UNRESOLVED :
-                return "unresolved";
-            case DependencyModel.BROKEN :
-                return "broken";
-            default :
-                return "unknown (" + state + ")";
-        }
-    }
-
-    /**
-     * Gets the dependency binding policy as a String.
-     * @param policy the policy.
-     * @return the String form of the policy.
-     */
-    private static String getDependencyBindingPolicy(int policy) {
-        switch(policy) {
-            case DependencyModel.DYNAMIC_BINDING_POLICY :
-                return "dynamic";
-            case DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY :
-                return "dynamic-priority";
-            case DependencyModel.STATIC_BINDING_POLICY :
-                return "static";
-            default :
-                return "unknown (" + policy + ")";
-        }
-    }
-
-    /**
-     * Gets the provided service state as a String.
-     * @param state the state.
-     * @return the String form of the state.
-     */
-    private static String getProvidedServiceState(int state) {
-        switch(state) {
-            case ProvidedService.REGISTERED :
-                return "registered";
-            case ProvidedService.UNREGISTERED :
-                return "unregistered";
-            default :
-                return "unknown (" + state + ")";
-        }
-    }
-
-    private final class RequestInfo {
-        /**
-         * Name of the required element.
-         */
-        public final String m_name;
-        /**
-         * Type of the required element.
-         */
-        public final String m_type;
-        /**
-         * Is 'all' elements of the type required.
-         */
-        public final boolean m_all;
-
-        /**
-         * Creates a RequestInfo.
-         * This constructor parses the parameter of the request.
-         * @param request the request
-         */
-        protected RequestInfo(final HttpServletRequest request) {
-            String factory = request.getParameter(FACTORY);
-            String instance = request.getParameter(INSTANCE);
-            String handler = request.getParameter(HANDLER);
-
-            if (factory != null) {
-                m_type = FACTORY;
-                m_name = factory;
-            } else if (instance != null) {
-                m_type = INSTANCE;
-                m_name = instance;
-            } else if (handler != null) {
-                m_type = HANDLER;
-                m_name = handler;
-            } else {
-                m_type = INSTANCE;
-                m_name = ALL;
-            }
-
-            if (ALL.equals(m_name)) {
-                m_all = true;
-            } else {
-                m_all = false;
-            }
-
-            request.setAttribute(IPOJOServlet.class.getName(), this);
-        }
-
-        /**
-         * toString method.
-         * @return the String form of the request.
-         * @see java.lang.Object#toString()
-         */
-        public String toString() {
-            return "Request: " + m_type + "=" + m_name;
-        }
-
-    }
-
-}
