Commit the base of the new iPOJO version.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@579239 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/annotations/pom.xml b/ipojo/annotations/pom.xml
index 94867bb..d4cb375 100644
--- a/ipojo/annotations/pom.xml
+++ b/ipojo/annotations/pom.xml
@@ -9,7 +9,7 @@
   <modelVersion>4.0.0</modelVersion>

   <artifactId>org.apache.felix.ipojo.annotations</artifactId>

   <packaging>bundle</packaging>

-  <version>0.7.3-SNAPSHOT</version>

+  <version>0.7.5-SNAPSHOT</version>

   <name>iPOJO Annotations</name>

   <build>

   <plugins>

diff --git a/ipojo/ant/pom.xml b/ipojo/ant/pom.xml
index a5ab4b8..4dfbdfe 100644
--- a/ipojo/ant/pom.xml
+++ b/ipojo/ant/pom.xml
@@ -9,18 +9,18 @@
   <modelVersion>4.0.0</modelVersion>

   <artifactId>org.apache.felix.ipojo.ant</artifactId>

   <packaging>bundle</packaging>

-  <version>0.7.3-SNAPSHOT</version>

+  <version>0.7.5-SNAPSHOT</version>

   <name>iPOJO Ant Task</name>

   <dependencies>

   	<dependency>

       <groupId>${pom.groupId}</groupId>

       <artifactId>org.apache.felix.ipojo.metadata</artifactId>

-      <version>0.7.3-SNAPSHOT</version>

+      <version>0.7.5-SNAPSHOT</version>

     </dependency>

     <dependency>

       <groupId>${pom.groupId}</groupId>

       <artifactId>org.apache.felix.ipojo.manipulator</artifactId>

-      <version>0.7.3-SNAPSHOT</version>

+      <version>0.7.5-SNAPSHOT</version>

     </dependency>

     <dependency>

       <groupId>xerces</groupId>

diff --git a/ipojo/arch/pom.xml b/ipojo/arch/pom.xml
index a63b8d6..37b31aa 100644
--- a/ipojo/arch/pom.xml
+++ b/ipojo/arch/pom.xml
@@ -8,7 +8,7 @@
   <modelVersion>4.0.0</modelVersion>
   <packaging>bundle</packaging>
   <name>Apache Felix iPOJO Arch Command</name>
-  <version>0.7.3-SNAPSHOT</version>
+  <version>0.7.5-SNAPSHOT</version>
   <artifactId>org.apache.felix.ipojo.arch</artifactId>
   <dependencies>
     <dependency>
diff --git a/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java b/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
index 4456cc8..d26522f 100644
--- a/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
+++ b/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
@@ -22,6 +22,7 @@
 
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.HandlerFactory;
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.shell.Command;
@@ -42,6 +43,12 @@
      * Factory services. 
      */
     private Factory[] m_factories;
+    
+    
+    /**
+     * Handler Factories.
+     */
+    private Factory[] m_handlers;
 
     /**
      * Get the command name.
@@ -58,7 +65,7 @@
      * @see org.apache.felix.shell.Command#getUsage()
      */
     public String getUsage() {
-        return "arch [-factories] [-instances] [-factory factory_name] [-instance instance_name]";
+        return "arch [-factories] [-instances] [-handlers] [-factory factory_name] [-instance instance_name]";
     }
 
     /**
@@ -78,39 +85,43 @@
      * @see org.apache.felix.shell.Command#execute(java.lang.String, java.io.PrintStream, java.io.PrintStream)
      */
     public void execute(String line, PrintStream out, PrintStream err) {
-        synchronized (this) {
-            String line2 = line.substring("arch".length()).trim();
-            
-            if (line2.equalsIgnoreCase("-instances") || line2.length() == 0) {
-                printInstances(out);
-                return;
-            }
-            
-            if (line2.equalsIgnoreCase("-factories")) {
-                printFactories(out);
-                return;
-            }
-            
-            if (line2.startsWith("-factory")) {
-                String name = line2.substring("-factory".length()).trim();
-                printFactory(name, out, err);
-                return;
-            }
-            
-            if (line2.startsWith("-instance")) {
-                String name = line2.substring("-instance".length()).trim();
-                printInstance(name, out, err);
-                return;
-            }
-            
-            err.println(getUsage());
+        String line2 = line.substring("arch".length()).trim();
+
+        if (line2.equalsIgnoreCase("-instances") || line2.length() == 0) {
+            printInstances(out);
+            return;
         }
 
+        if (line2.equalsIgnoreCase("-factories")) {
+            printFactories(out);
+            return;
+        }
+
+        if (line2.startsWith("-factory")) {
+            String name = line2.substring("-factory".length()).trim();
+            printFactory(name, out, err);
+            return;
+        }
+
+        if (line2.startsWith("-instance")) {
+            String name = line2.substring("-instance".length()).trim();
+            printInstance(name, out, err);
+            return;
+        }
+
+        if (line2.startsWith("-handlers")) {
+            printHandlers(out);
+            return;
+        }
+
+        err.println(getUsage());
     }
     
     /**
      * Print instance list.
-     * @param out : default print stream
+     * 
+     * @param out :
+     *            default print stream
      */
     private void printInstances(PrintStream out) {
         for (int i = 0; i < m_archs.length; i++) {
@@ -150,7 +161,11 @@
      */
     private void printFactories(PrintStream out) {
         for (int i = 0; i < m_factories.length; i++) {
-            out.println("Factory " + m_factories[i].getName());
+            if (m_factories[i].getMissingHandlers().size() == 0) {
+                out.println("Factory " + m_factories[i].getName() + " (VALID)");
+            } else {
+                out.println("Factory " + m_factories[i].getName() + " (INVALID : " + m_factories[i].getMissingHandlers() + ")");
+            }
         }
     }
     
@@ -169,4 +184,23 @@
         }
         err.println("Factory " + name + " not found");
     }
+    
+    /**
+     * Print the list of available handlers (and validity).
+     * @param out : default print stream
+     */
+    private void printHandlers(PrintStream out) {
+        for (int i = 0; i < m_handlers.length; i++) {
+            HandlerFactory hf = (HandlerFactory) m_handlers[i];
+            String name = hf.getHandlerName();
+            if ("composite".equals(hf.getType())) {
+                name = name + " [composite]";
+            }
+            if (hf.getMissingHandlers().size() == 0) {
+                out.println("Handler " + name + " (VALID)");
+            } else {
+                out.println("Handler " + name + " (INVALID : " + hf.getMissingHandlers() + ")");
+            }
+        }
+    }
 }
diff --git a/ipojo/arch/src/main/resources/metadata.xml b/ipojo/arch/src/main/resources/metadata.xml
index 7934090..6dcfb62 100644
--- a/ipojo/arch/src/main/resources/metadata.xml
+++ b/ipojo/arch/src/main/resources/metadata.xml
@@ -3,7 +3,8 @@
 	<Component className="org.apache.felix.ipojo.arch.ArchCommandImpl">
 		  <Provides/>
 		  <Requires field="m_archs" optional="true"/>
-		  <Requires field="m_factories" optional="true"/>
+		  <Requires field="m_factories" optional="true" filter="(!(handler.name=*))"/>
+		  <Requires field="m_handlers" optional="true" filter="(handler.name=*)"/>
 	</Component>
 	<instance component="org.apache.felix.ipojo.arch.ArchCommandImpl" name="ArchCommand"/>
 </iPOJO>
\ No newline at end of file
diff --git a/ipojo/core/pom.xml b/ipojo/core/pom.xml
index 241023b..3eff517 100644
--- a/ipojo/core/pom.xml
+++ b/ipojo/core/pom.xml
@@ -9,7 +9,7 @@
   <packaging>bundle</packaging>
   <name>Apache Felix iPOJO</name>
   <artifactId>org.apache.felix.ipojo</artifactId>
-  <version>0.7.3-SNAPSHOT</version>
+  <version>0.7.5-SNAPSHOT</version>
   <dependencies>
     <dependency>
       <groupId>${pom.groupId}</groupId>
@@ -24,12 +24,12 @@
     <dependency>
       <groupId>${pom.groupId}</groupId>
       <artifactId>org.apache.felix.ipojo.metadata</artifactId>
-      <version>0.7.3-SNAPSHOT</version>
+      <version>0.7.5-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>${pom.groupId}</groupId>
       <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
-      <version>0.7.3-SNAPSHOT</version>
+      <version>0.7.5-SNAPSHOT</version>
     </dependency>
   </dependencies>
   <build>
@@ -64,20 +64,36 @@
               	org.objectweb.asm*;-split-package:=merge-first
             </Private-Package>
             <Export-Package>
-              org.apache.felix.ipojo; version="0.7.3", 
-              org.apache.felix.ipojo.metadata; version="0.7.3", 
-              org.apache.felix.ipojo.architecture; version="0.7.3", 
-              org.apache.felix.ipojo.parser; version="0.7.3",
-              org.apache.felix.ipojo.util; version="0.7.3",
-              org.apache.felix.ipojo.handlers.dependency; version="0.7.3",
-              org.apache.felix.ipojo.handlers.providedservice; version="0.7.3", 
-              org.apache.felix.ipojo.composite; version="0.7.3",
+              org.apache.felix.ipojo; version="0.7.5", 
+              org.apache.felix.ipojo.metadata; version="0.7.5", 
+              org.apache.felix.ipojo.architecture; version="0.7.5", 
+              org.apache.felix.ipojo.parser; version="0.7.5",
+              org.apache.felix.ipojo.util; version="0.7.5",
+              org.apache.felix.ipojo.handlers.dependency; version="0.7.5",
+              org.apache.felix.ipojo.handlers.providedservice; version="0.7.5", 
+              org.apache.felix.ipojo.composite; version="0.7.5",
               org.osgi.service.cm,
               org.osgi.service.log
             </Export-Package>
+            <_donotcopy>(CVS|.svn|.+.bak|~.+|metadata.xml)</_donotcopy>
           </instructions>
         </configuration>
       </plugin>
+       <plugin>
+	      <groupId>org.apache.felix</groupId>
+	      <artifactId>org.apache.felix.ipojo.plugin</artifactId>
+              <version>${pom.version}</version>
+		  <executions>
+          	<execution>
+            	<goals>
+	              <goal>ipojo-bundle</goal>
+               </goals>
+            <configuration>
+   				<metadata>metadata.xml</metadata>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index 7b655df..7504220 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -33,8 +33,12 @@
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedServiceFactory;
@@ -46,167 +50,125 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ComponentFactory implements Factory, ManagedServiceFactory {
+public class ComponentFactory implements Factory, ManagedServiceFactory, TrackerCustomizer {
 
     /**
      * List of the managed instance name. This list is shared by all factories.
      */
-    private static List m_instancesName = new ArrayList();
+    protected static List m_instancesName = new ArrayList();
+    
+    /**
+     * Component-Type description exposed by the factory service.
+     */
+    protected ComponentDescription m_componentDesc;
     
     /**
      * List of the managed instance managers. The key of this map is the
-     * name (i.e. PID) of the created instance
+     * name (i.e. instance names) of the created instance
      */
-    private Map m_componentInstances = new HashMap();
-
-
+    protected Map m_componentInstances = new HashMap();
+    
     /**
-     * True if the component is a composition.
+     * Component Type provided by this factory.
      */
-    private boolean m_isComposite = false;
-
+    protected Element m_componentMetadata;
+    
     /**
      * The bundle context reference.
      */
-    private BundleContext m_context = null;
+    protected BundleContext m_context = null;    
+    
+    /**
+     * Factory Name. Could be the component class name if the
+     * factory name is not set.
+     */
+    protected String m_factoryName;
 
     /**
-     * Component Implementation class.
+     * List of required handler.
      */
-    private byte[] m_clazz = null;
+    protected List m_handlerIdentifiers = new ArrayList();
 
     /**
-     * Component Implementation Class Name.
+     * List of listeners.
      */
-    private String m_componentClassName = null;
+    protected List m_listeners = new ArrayList(5);
+    
+    /**
+     * Logger for the factory (and all component instance).
+     */
+    protected Logger m_logger;
 
     /**
-     * Composition Name.
+     * Factory state.
      */
-    private String m_typeName = null;
+    protected int m_state = Factory.INVALID;
+
+    /**
+     * Tracker used to track required handler factories.
+     */
+    protected Tracker m_tracker;
+    
+    /**
+     * Component Type Name.
+     */
+    protected String m_typeName = null;
 
     /**
      * Class loader to delegate loading.
      */
     private FactoryClassloader m_classLoader = null;
-
+    
     /**
-     * Component Type provided by this factory. //TODO Should we keep this ?
-     * reference ?
+     * Component Implementation class.
      */
-    private Element m_componentMetadata;
-
+    private byte[] m_clazz = null;
+    
     /**
-     * Factory Name (i.e. Factory PID). Could be the component class name if the
-     * factory name is not set.
+     * Component Implementation Class Name.
      */
-    private String m_factoryName;
-
-    /**
-     * Service Registration of this factory (Factory & ManagedServiceFactory).
-     */
-    private ServiceRegistration m_sr;
-
-    /**
-     * Component-Type description exposed by the factory service.
-     */
-    private ComponentDescription m_componentDesc;
-
-    /**
-     * Logger for the factory (and all component instance).
-     */
-    private Logger m_logger;
+    private String m_componentClassName = null;
     
     /**
      * Index used to generate instance name if not set.
      */
     private long m_index = 0;
-
+    
     /**
-     * FactoryClassloader.
+     * Service Registration of this factory (Factory & ManagedServiceFactory).
      */
-    private class FactoryClassloader extends ClassLoader {
-
-        /**
-         * Map of defined classes [Name, Class Object].
-         */
-        private Map m_definedClasses = new HashMap();
-
-        /**
-         * load the class.
-         * 
-         * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
-         * @param name : the name of the class
-         * @param resolve : should be the class resolve now ?
-         * @return : the loaded class
-         * @throws ClassNotFoundException : the class to load is not found
-         */
-        protected synchronized Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
-            return m_context.getBundle().loadClass(name);
-        }
-
-        /**
-         * Return the URL of the asked resource.
-         * 
-         * @param arg : the name of the resource to find.
-         * @return the URL of the resource.
-         * @see java.lang.ClassLoader#getResource(java.lang.String)
-         */
-        public URL getResource(String arg) {
-            return m_context.getBundle().getResource(arg);
-        }
-
-        /**
-         * The defineClass method.
-         * 
-         * @param name : name of the class
-         * @param b : the byte array of the class
-         * @param domain : the protection domain
-         * @return : the defined class.
-         * @throws Exception : if a problem is detected during the loading
-         */
-        public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
-            if (m_definedClasses.containsKey(name)) {
-                return (Class) m_definedClasses.get(name);
-            }
-            final Class c = super.defineClass(name, b, 0, b.length, domain);
-            m_definedClasses.put(name, c);
-            return c;
-        }
+    private ServiceRegistration m_sr;
+    
+    /**
+     * Create a instance manager factory. The class is given in parameter. The
+     * component type is not a composite.
+     * @param bc : bundle context
+     * @param clazz : the component class
+     * @param cm : metadata of the component
+     */
+    public ComponentFactory(BundleContext bc, byte[] clazz, Element cm) {
+        this(bc, cm);
+        m_clazz = clazz;
     }
-
+    
     /**
      * Create a instance manager factory.
-     * 
      * @param bc : bundle context
      * @param cm : metadata of the component to create
      */
     public ComponentFactory(BundleContext bc, Element cm) {
         m_context = bc;
         m_componentMetadata = cm;
-        if (cm.getName().equalsIgnoreCase("composite")) {
-            m_componentClassName = null;
-            m_isComposite = true;
-            // Get the name
-            if (cm.containsAttribute("name")) {
-                m_typeName = cm.getAttribute("name");
-            } else {
-                System.err.println("A composite needs a name");
-                return;
-            }
-        } else {
-            if (cm.containsAttribute("className")) {
-                m_componentClassName = cm.getAttribute("className");
-            } else {
-                System.err.println("A component needs a class name");
-                return;
-            }
-            // Get the name
-            if (cm.containsAttribute("name")) {
-                m_typeName = cm.getAttribute("name");
-            }
+        
+        if (! check(cm)) {
+            return;
         }
         
+        // Get the name
+        if (cm.containsAttribute("name")) {
+            m_typeName = cm.getAttribute("name");
+        }
+
         if (m_typeName != null) {
             m_logger = new Logger(m_context, m_typeName, Logger.WARNING);
         } else {
@@ -214,59 +176,184 @@
         }
         
         computeFactoryName();
+        computeRequiredHandlers();
         
     }
     
     /**
-     * Create a instance manager factory. The class is given in parameter. The
-     * component type is not a composite.
-     * 
-     * @param bc : bundle context
-     * @param clazz : the component class
-     * @param cm : metadata of the component
+     * Add a factory listener.
+     * @param l : the factory listener to add
+     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
      */
-    public ComponentFactory(BundleContext bc, byte[] clazz, Element cm) {
-        m_context = bc;
-        m_clazz = clazz;
-        m_componentClassName = cm.getAttribute("className");
-        m_componentMetadata = cm;
-        
-        // Get the name
-        if (cm.containsAttribute("name")) {
-            m_typeName = cm.getAttribute("name");
-            m_logger = new Logger(m_context, m_typeName, Logger.WARNING);
-        } else {
-            m_logger = new Logger(m_context, m_componentClassName, Logger.WARNING);
+    public void addFactoryStateListener(FactoryStateListener l) {
+        synchronized (m_listeners) {
+            m_listeners.add(l);
         }
-    
-        computeFactoryName();
+        // TODO do we need to notify the actual state of the factory to the new listener ?
     }
 
     /**
-     * Return the bundle context.
-     * 
-     * @return the Bundle Context.
+     * A new handler factory is detected.
+     * Test if the factory can be used or not.
+     * @param reference : the new service reference.
+     * @return true if the given factory reference match with a required handler.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
      */
-    protected BundleContext getBundleContext() {
-        return m_context;
-    }
-    
-    protected String getComponentTypeName() {
-        return m_typeName;
+    public boolean addingService(ServiceReference reference) {
+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            if (hi.m_reference == null && match(hi, reference)) {
+                hi.setReference(reference);
+                computeFactoryState();
+                return true;
+            }
+        }
+        return false;
     }
 
     /**
-     * Get the implementation class of the component type.
-     * 
-     * @return the name of the component-type implementation class.
+     * Check method : allow a factory to check if given element are correct.
+     * A component factory metadata are correct if they contain the 'classname' attribute.
+     * @param cm : the metadata
+     * @return true if the metadata are correct
      */
-    protected String getComponentClassName() {
-        return m_componentClassName;
+    public boolean check(Element cm) {
+        if (cm.containsAttribute("className")) {
+            m_componentClassName = cm.getAttribute("className");
+            return true;
+        } else {
+            System.err.println("A component needs a class name : " + cm);
+            return false;
+        }
     }
 
     /**
+     * Create an instance. The given configuration needs to contain the 'name'
+     * property.
+     * @param configuration : configuration of the created instance.
+     * @return the created component instance.
+     * @throws UnacceptableConfiguration : occurs if the given configuration is
+     * not consistent with the component type of this factory.
+     * @throws MissingHandlerException  : occurs if an handler is unavailable when the instance is created.
+     * @throws org.apache.felix.ipojo.ConfigurationException : occurs when the instance or type configuration are not correct.
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     */
+    public synchronized ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {
+        return createComponentInstance(configuration, null);
+    }
+    
+    /**
+     * Create an instance. The given configuration needs to contain the 'name'
+     * property.
+     * @param configuration : configuration of the created instance.
+     * @param serviceContext : the service context to push for this instance.
+     * @return the created component instance.
+     * @throws UnacceptableConfiguration : occurs if the given configuration is
+     * not consistent with the component type of this factory.
+     * @throws MissingHandlerException : occurs when an handler is unavailable when creating the instance.
+     * @throws org.apache.felix.ipojo.ConfigurationException : when the instance configuration failed.
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     */
+    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {
+        if (m_state == INVALID) {
+            throw new MissingHandlerException(getMissingHandlers());
+        }
+        
+        if (configuration == null) {
+            configuration = new Properties();
+        }
+        
+        try {
+            checkAcceptability(configuration);
+        } catch (UnacceptableConfiguration e) {
+            m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+            throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage());
+        }
+
+        
+        String n = null;
+        if (configuration.get("name") != null) {
+            n = (String) configuration.get("name");
+        } else {
+            n = generateName();
+            configuration.put("name", n);
+        }
+        
+        if (m_instancesName.contains(n)) {
+            throw new UnacceptableConfiguration("Name already used : " + n);
+        } else {
+            m_instancesName.add(n);
+        }
+
+        BundleContext context = null;
+        if (serviceContext == null) {
+            context = new IPojoContext(m_context);
+        } else {
+            context = new IPojoContext(m_context, serviceContext);
+        }
+        List handlers = new ArrayList();
+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            handlers.add(getHandlerInstance(hi, serviceContext));
+        }
+        InstanceManager instance = new InstanceManager(this, context, (HandlerManager[]) handlers.toArray(new HandlerManager[0]));
+        instance.configure(m_componentMetadata, configuration);
+
+        m_componentInstances.put(n, instance);
+        instance.start();
+        return instance;
+    }
+
+    /**
+     * Define a class.
+     * @param name : qualified name of the class
+     * @param b : byte array of the class
+     * @param domain : protection domain of the class
+     * @return the defined class object
+     * @throws Exception : an exception occur during the definition
+     */
+    public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
+        if (m_classLoader == null) {
+            m_classLoader = new FactoryClassloader();
+        }
+        return m_classLoader.defineClass(name, b, domain);
+    }
+    
+    /**
+     * Delete an instance.
+     * @param in : name of the instance to delete
+     * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
+     */
+    public synchronized void deleted(String in) {
+        m_instancesName.remove(in);
+        final ComponentInstance cm = (ComponentInstance) m_componentInstances.remove(in);
+        if (cm == null) {
+            return; // do nothing, the component does not exist !
+        } else {
+            cm.dispose();
+        }
+    }
+
+    /**
+     * Get the component type description.
+     * @return the component type description object. Null if not already computed.
+     */
+    public ComponentDescription getComponentDescription() {
+        return m_componentDesc;
+    }
+
+    /**
+     * Get the component type description attached to this factory.
+     * @return : the component type description
+     * @see org.apache.felix.ipojo.Factory#getDescription()
+     */
+    public Element getDescription() {
+        if (m_componentDesc == null) { return new Element("No description available for " + getName(), ""); }
+        return m_componentDesc.getDescription();
+    }
+    
+    /**
      * Get the logger used by instances of he current factory.
-     * 
      * @return the factory logger.
      */
     public Logger getLogger() {
@@ -274,9 +361,325 @@
     }
     
     /**
+     * Get the list of missing handlers.
+     * @return the list of missing handlers (namespace:name)
+     * @see org.apache.felix.ipojo.Factory#getMissingHandlers()
+     */
+    public List getMissingHandlers() {
+        List l = new ArrayList();
+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            if (hi.m_reference == null) {
+                l.add(hi.getFullName());
+            }
+        }
+        return l;
+    }
+
+    /**
+     * Get the name of this factory.
+     * 
+     * @return the name of this factory
+     * @see org.apache.felix.ipojo.Factory#getName()
+     */
+    public String getName() {
+        if (m_factoryName != null) {
+            return m_factoryName;
+        } else if (m_typeName != null) {
+            return m_typeName;
+        } else {
+            return m_componentClassName;
+        }
+    }
+
+    /**
+     * Get the list of required handlers.
+     * @return the list of required handlers (namespace:name)
+     * @see org.apache.felix.ipojo.Factory#getRequiredHandlers()
+     */
+    public List getRequiredHandlers() {
+        List l = new ArrayList();
+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            l.add(hi.getFullName());
+        }
+        return l;
+    }
+    
+    /**
+     * Return the URL of a resource.
+     * @param resName : resource name
+     * @return the URL of the resource
+     */
+    public URL getResource(String resName) {
+        return m_context.getBundle().getResource(resName);
+    }
+
+    /**
+     * Check if the given configuration is acceptable as a component instance
+     * configuration. This method checks that if all the configurable properties
+     * have a value.
+     * @param conf : the configuration to check
+     * @return true when the configuration seems to be acceptable
+     */
+    public boolean isAcceptable(Dictionary conf) {
+        try {
+            checkAcceptability(conf);
+        } catch (UnacceptableConfiguration e) { 
+            return false; 
+        } catch (MissingHandlerException e) { 
+            return false;  
+        }
+        return true;
+    }
+
+    /**
+     * Load a class.
+     * @param className : name of the class to load
+     * @return the resulting Class object
+     * @throws ClassNotFoundException : happen when the class is not found
+     */
+    public Class loadClass(String className) throws ClassNotFoundException {
+        if (m_clazz != null && className.equals(m_componentClassName)) {
+            // Used the factory classloader to load the component implementation
+            // class
+            if (m_classLoader == null) {
+                m_classLoader = new FactoryClassloader();
+            }
+            try {
+                return m_classLoader.defineClass(m_componentClassName, m_clazz, null);
+            } catch (Exception e) {
+                throw new ClassNotFoundException("[Bundle " + m_context.getBundle().getBundleId() + "] Cannot define the class : " + className, e);
+            }
+        }
+        return m_context.getBundle().loadClass(className);
+    }
+
+    /**
+     * A used handler factory is modified.
+     * @param reference : the service reference
+     * @param service : the Factory object (if already get)
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+        // Noting to do
+    }
+
+    /**
+     * Reconfigure an existing instance.
+     * @param properties : the new configuration to push.
+     * @throws UnacceptableConfiguration : occurs if the new configuration is
+     * not consistent with the component type.
+     * @throws MissingHandlerException : occurs if the current factory is not valid.
+     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
+     */
+    public synchronized void reconfigure(Dictionary properties) throws UnacceptableConfiguration, MissingHandlerException {
+        if (properties == null || properties.get("name") == null) {
+            throw new UnacceptableConfiguration("The configuration does not contains the \"name\" property");
+        }
+        final String name = (String) properties.get("name");
+        InstanceManager cm = (InstanceManager) m_componentInstances.get(name);
+        
+        if (cm == null) {
+            return; // The instance does not exist.
+        } else {
+            checkAcceptability(properties); // Test if the configuration is acceptable
+        }
+        cm.reconfigure(properties); // re-configure the component
+    }
+
+    /**
+     * A used factory disappears.
+     * @param reference : service reference.
+     * @param service : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        // Look for the implied reference and invalid the handler identifier
+        boolean touched = false;
+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            if (reference.equals(hi.getReference())) {
+                hi.setReference(null); // This method will unget the service.
+                touched = true;
+            }
+        }
+        if (touched) { computeFactoryState(); }
+    }
+
+    /**
+     * Remove a factory listener.
+     * @param l : the factory listener to remove
+     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void removeFactoryStateListener(FactoryStateListener l) {
+        synchronized (m_listeners) {
+            m_listeners.remove(l);
+        }
+    }
+
+    /**
+     * Start the factory.
+     */
+    public synchronized void start() {
+        if (m_componentDesc != null) { // Already started.
+            return;
+        } 
+        
+        try {
+            String filter = "(&(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")"
+                    + "(" + Handler.HANDLER_NAME_PROPERTY + "=*)" + "(" + Handler.HANDLER_NAMESPACE_PROPERTY + "=*)" /* Look only for handlers */
+                    + "(" + Handler.HANDLER_TYPE_PROPERTY + "=" + PrimitiveHandler.HANDLER_TYPE + ")" 
+                    + "(factory.state=1)"
+                    + ")";
+            m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
+            m_tracker.open();
+            
+        } catch (InvalidSyntaxException e) {
+            m_logger.log(Logger.ERROR, "A factory filter is not valid: " + e.getMessage());
+            return;
+        }
+        
+        computeFactoryState();
+
+        if (m_factoryName == null) {
+            return;
+        }
+        
+        // Exposition of the factory service
+        m_sr = m_context.registerService(new String[] { Factory.class.getName(), ManagedServiceFactory.class.getName() }, this, getProperties());
+    }
+
+    /**
+     * Stop all the instance managers.
+     */
+    public synchronized void stop() {
+        if (m_sr != null) {
+            m_sr.unregister();
+            m_sr = null;
+        }
+        
+        if (m_tracker != null) {        
+            m_tracker.close();
+        }
+        
+        final Collection col = m_componentInstances.values();
+        final Iterator it = col.iterator();
+        while (it.hasNext()) {
+            InstanceManager ci = (InstanceManager) it.next();
+            if (ci.getState() != ComponentInstance.DISPOSED) {
+                ci.kill();
+            }
+            m_instancesName.remove(ci.getInstanceName());
+        }
+        
+        m_componentInstances.clear();
+        
+        // Release each handler
+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            if (hi.getReference() != null) {
+                hi.setReference(null);
+            }
+        }
+        
+        m_tracker = null;
+        m_componentDesc = null;
+        m_classLoader = null;
+        m_clazz = null;
+        m_state = INVALID;
+    }
+    
+    /**
+     * Create of update an instance.
+     * @param in : name of the instance
+     * @param properties : configuration of the instance
+     * @throws ConfigurationException : if the configuration is not consistent
+     * for this component type
+     * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String,
+     * java.util.Dictionary)
+     */
+    public synchronized void updated(String in, Dictionary properties) throws ConfigurationException {
+        final InstanceManager cm = (InstanceManager) m_componentInstances.get(in);
+        if (cm == null) {
+            try {
+                properties.put("name", in); // Add the name in the configuration
+                createComponentInstance(properties);
+            } catch (UnacceptableConfiguration e) {
+                m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+                throw new ConfigurationException(properties.toString(), e.getMessage());
+            } catch (MissingHandlerException e) {
+                m_logger.log(Logger.ERROR, "Handler not available : " + e.getMessage());
+                throw new ConfigurationException(properties.toString(), e.getMessage());
+            } catch (org.apache.felix.ipojo.ConfigurationException e) {
+                m_logger.log(Logger.ERROR, "The Component Type metadata are not correct : " + e.getMessage());
+                throw new ConfigurationException(properties.toString(), e.getMessage());
+            }
+        } else {
+            try {
+                properties.put("name", in); // Add the name in the configuration
+                reconfigure(properties); // re-configure the component
+            } catch (UnacceptableConfiguration e) {
+                m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+                throw new ConfigurationException(properties.toString(), e.getMessage());
+            } catch (MissingHandlerException e) {
+                m_logger.log(Logger.ERROR, "The facotry is not valid, at least one handler is missing : " + e.getMessage());
+                throw new ConfigurationException(properties.toString(), e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Test is a configuration is acceptable for the factory.
+     * @param conf : the configuration to test.
+     * @throws UnacceptableConfiguration : the configuration is not acceptable.
+     * @throws MissingHandlerException : the factory is not valid.
+     */
+    protected void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
+        computeFactoryState();
+        
+        if (m_state == Factory.INVALID) {
+            throw new MissingHandlerException(getMissingHandlers());
+        }
+        
+        final PropertyDescription[] props = m_componentDesc.getProperties();
+        for (int i = 0; i < props.length; i++) {
+            final PropertyDescription pd = props[i];
+            // Failed if the props has no default value and the configuration does not push a value
+            if (pd.getValue() == null && conf.get(pd.getName()) == null) {
+                throw new UnacceptableConfiguration("The configuration does not contains the \"" + pd.getName() + "\" property");
+            }
+        }
+    }
+    
+    /**
+     * Compute the component type description.
+     * The factory must be valid when calling this method.
+     * @throws org.apache.felix.ipojo.ConfigurationException if one handler has rejected the configuration.
+     */
+    protected void computeDescription() throws org.apache.felix.ipojo.ConfigurationException {
+        List l = new ArrayList();
+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            l.add(hi.getFullName());
+        }
+
+        m_componentDesc = new ComponentDescription(getName(), m_componentClassName, m_state, l, getMissingHandlers(), m_context.getBundle().getBundleId());
+         
+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            HandlerManager hm = getHandlerInstance(hi, null);
+            hm.getHandler();
+            Handler ch =  hm.getHandler();
+            ch.initializeComponentFactory(m_componentDesc, m_componentMetadata);
+            ((Pojo) ch).getComponentInstance().dispose();
+        }
+    }
+
+    /**
      * Compute the factory name.
      */
-    private void computeFactoryName() {
+    protected void computeFactoryName() {
         if (m_componentMetadata.containsAttribute("factory")) {
             // DEPRECATED BLOCK
             if (m_componentMetadata.getAttribute("factory").equalsIgnoreCase("no")) {
@@ -309,395 +712,103 @@
             return;
         }
     }
-
+    
     /**
-     * Stop all the instance managers.
+     * Compute factory state.
      */
-    public synchronized void stop() {
-        final Collection col = m_componentInstances.values();
-        final Iterator it = col.iterator();
-        while (it.hasNext()) {
-            final ComponentInstance ci = (ComponentInstance) it.next();
-            if (ci.isStarted()) {
-                if (ci instanceof CompositeManager) { 
-                    ((CompositeManager) ci).kill();
-                } else { 
-                    ((InstanceManager) ci).kill(); 
-                } 
+    protected void computeFactoryState() {
+        boolean isValid = true;
+        for (int i = 0; isValid && i < m_handlerIdentifiers.size(); i++) {
+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+            isValid = hi.m_reference != null;
+        }
+
+        if (isValid && m_componentDesc == null) {
+            try {
+                computeDescription();
+            } catch (org.apache.felix.ipojo.ConfigurationException e) {
+                m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
+                stop();
+                return;
             }
-            m_instancesName.remove(ci.getInstanceName());
+        }
+
+        if (isValid && m_state == INVALID) {
+            m_state = VALID;
+            if (m_sr != null) {
+                m_sr.setProperties(getProperties());
+            }
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, VALID);
+            }
+            return;
+        }
+
+        if (!isValid && m_state == VALID) {
+            m_state = INVALID;
+
+            final Collection col = m_componentInstances.values();
+            final Iterator it = col.iterator();
+            while (it.hasNext()) {
+                InstanceManager ci = (InstanceManager) it.next();
+                if (ci.getState() != ComponentInstance.DISPOSED) {
+                    ci.kill();
+                }
+                m_instancesName.remove(ci.getInstanceName());
+            }
+
+            m_componentInstances.clear();
+
+            if (m_sr != null) {
+                m_sr.setProperties(getProperties());
+            }
+
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
+            }
+            return;
+        }
+    }
+    
+    /**
+     * Compute required handlers.
+     */
+    protected void computeRequiredHandlers() {
+        Element[] elems = m_componentMetadata.getElements();
+        for (int i = 0; i < elems.length; i++) {
+            Element current = elems[i]; 
+            if (current.getName().equals("manipulation")) { continue; }
+            HandlerIdentifier hi = new HandlerIdentifier(current.getName(), current.getNameSpace());
+            if (! m_handlerIdentifiers.contains(hi)) { m_handlerIdentifiers.add(hi); }
         }
         
-        m_componentInstances.clear();
-        if (m_sr != null) {
-            m_sr.unregister();
+        // Add architecture if needed
+        HandlerIdentifier hi = new HandlerIdentifier("architecture", "");
+        if (! m_handlerIdentifiers.contains(hi) && m_componentMetadata.containsAttribute("architecture") && m_componentMetadata.getAttribute("architecture").equalsIgnoreCase("true")) {
+            m_handlerIdentifiers.add(hi);
         }
-        m_sr = null;
-        m_componentDesc = null;
-    }
-
-    /**
-     * Start all the instance managers.
-     */
-    public synchronized void start() {
-        if (m_componentDesc != null) { // Already started.
-            return;
+        
+        // Add lifecycle callback if immediate = true
+        HandlerIdentifier hi2 = new HandlerIdentifier("callback", "");
+        if (! m_handlerIdentifiers.contains(hi2) && m_componentMetadata.containsAttribute("immediate") && m_componentMetadata.getAttribute("immediate").equalsIgnoreCase("true")) {
+            m_handlerIdentifiers.add(hi2);
         }
-        final Properties props = new Properties();
-
-        // create a ghost component
-        if (!m_isComposite) {
-            final InstanceManager ghost = new InstanceManager(this, new IPojoContext(m_context));
-            final Properties p = new Properties();
-            p.put("name", "ghost");
-            ghost.configure(m_componentMetadata, p);
-            m_componentDesc = ghost.getComponentDescription();
-        } else {
-            final CompositeManager ghost = new CompositeManager(this, new IPojoContext(m_context));
-            final Properties p = new Properties();
-            p.put("name", "ghost");
-            ghost.configure(m_componentMetadata, p);
-            m_componentDesc = ghost.getComponentDescription();
-        }
-
-        // Check if the factory should be exposed
-        if (m_factoryName == null) {
-            return;
-        }
-
-        if (!m_isComposite) {
-            props.put("component.class", m_componentClassName);
-        } else {
-            props.put("component.class", "no implementation class");
-        }
-        props.put("factory.name", m_factoryName);
-        if (m_typeName != null) {
-            props.put("component.type", m_typeName);
-        }
-        props.put("component.providedServiceSpecifications", m_componentDesc.getprovidedServiceSpecification());
-        props.put("component.properties", m_componentDesc.getProperties());
-        props.put("component.description", m_componentDesc);
-        props.put("component.desc", m_componentDesc.toString());
-
-        // Add Factory PID to the component properties
-        props.put(Constants.SERVICE_PID, m_factoryName);
-
-        // Exposition of the factory service
-        m_sr = m_context.registerService(new String[] { Factory.class.getName(), ManagedServiceFactory.class.getName() }, this, props);
     }
 
     /**
      * Callback called by instance when disposed.
-     * 
      * @param ci : the destroyed instance
      */
-    protected synchronized void disposed(ComponentInstance ci) {
+    protected void disposed(ComponentInstance ci) {
         m_instancesName.remove(ci.getInstanceName());
         m_componentInstances.remove(ci.getInstanceName());
     }
-
-    /**
-     * Get the component type description attached to this factory.
-     * 
-     * @return : the component type description
-     * @see org.apache.felix.ipojo.Factory#getDescription()
-     */
-    public Element getDescription() {
-        return m_componentDesc.getDescription();
-    }
-
-    /**
-     * Load a class.
-     * 
-     * @param className : name of the class to load
-     * @return the resulting Class object
-     * @throws ClassNotFoundException : happen when the class is not found
-     */
-    public Class loadClass(String className) throws ClassNotFoundException {
-        if (m_clazz != null && className.equals(m_componentClassName)) {
-            // Used the factory classloader to load the component implementation
-            // class
-            if (m_classLoader == null) {
-                m_classLoader = new FactoryClassloader();
-            }
-            try {
-                return m_classLoader.defineClass(m_componentClassName, m_clazz, null);
-            } catch (Exception e) {
-                throw new ClassNotFoundException("[Bundle " + m_context.getBundle().getBundleId() + "] Cannot define the class : " + className, e);
-            }
-        }
-        return m_context.getBundle().loadClass(className);
-    }
-
-    /**
-     * Define a class.
-     * 
-     * @param name : qualified name of the class
-     * @param b : byte array of the class
-     * @param domain : protection domain of the class
-     * @return the defined class object
-     * @throws Exception : an exception occur during the definition
-     */
-    public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
-        if (m_classLoader == null) {
-            m_classLoader = new FactoryClassloader();
-        }
-        return m_classLoader.defineClass(name, b, domain);
-    }
-
-    /**
-     * Return the URL of a resource.
-     * 
-     * @param resName : resource name
-     * @return the URL of the resource
-     */
-    public URL getResource(String resName) {
-        return m_context.getBundle().getResource(resName);
-    }
-
-    /**
-     * Create an instance. The given configuration needs to contain the 'name'
-     * property.
-     * 
-     * @param configuration : configuration of the created instance.
-     * @return the created component instance.
-     * @throws UnacceptableConfiguration : occurs if the given configuration is
-     * not consistent with the component type of this factory.
-     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
-     */
-    public synchronized ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration {
-        if (configuration == null) {
-            configuration = new Properties();
-        }
-        
-        try {
-            checkAcceptability(configuration);
-        } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
-            throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e);
-        }
-        
-        String pid = null;
-        if (configuration.get("name") != null) {
-            pid = (String) configuration.get("name");
-        } else {
-            pid = generateName();
-            configuration.put("name", pid);
-        }
-
-        if (m_instancesName.contains(pid)) {
-            throw new UnacceptableConfiguration("Name already used : " + pid);
-        } else {
-            m_instancesName.add(pid);
-        }
-
-        final IPojoContext context = new IPojoContext(m_context);
-        ComponentInstance instance = null;
-        if (!m_isComposite) {
-            final InstanceManager inst = new InstanceManager(this, context);
-            inst.configure(m_componentMetadata, configuration);
-            instance = inst;
-        } else {
-            final CompositeManager inst = new CompositeManager(this, context);
-            inst.configure(m_componentMetadata, configuration);
-            instance = inst;
-        }
-
-        m_componentInstances.put(pid, instance);
-        instance.start();
-        return instance;
-    }
-
-    /**
-     * Create an instance. The given configuration needs to contain the 'name'
-     * property.
-     * 
-     * @param configuration : configuration of the created instance.
-     * @param serviceContext : the service context to push for this instance.
-     * @return the created component instance.
-     * @throws UnacceptableConfiguration : occurs if the given configuration is
-     * not consistent with the component type of this factory.
-     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
-     */
-    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration {
-        if (configuration == null) {
-            configuration = new Properties();
-        }
-        
-        try {
-            checkAcceptability(configuration);
-        } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
-            throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage());
-        }
-
-        
-        String pid = null;
-        if (configuration.get("name") != null) {
-            pid = (String) configuration.get("name");
-        } else {
-            pid = generateName();
-            configuration.put("name", pid);
-        }
-        
-        if (m_instancesName.contains(pid)) {
-            throw new UnacceptableConfiguration("Name already used : " + pid);
-        } else {
-            m_instancesName.add(pid);
-        }
-
-        final IPojoContext context = new IPojoContext(m_context, serviceContext);
-        ComponentInstance instance = null;
-        if (!m_isComposite) {
-            final InstanceManager inst = new InstanceManager(this, context);
-            inst.configure(m_componentMetadata, configuration);
-            instance = inst;
-        } else {
-            final CompositeManager inst = new CompositeManager(this, context);
-            inst.configure(m_componentMetadata, configuration);
-            instance = inst;
-        }
-
-        m_componentInstances.put(pid, instance);
-        instance.start();
-        return instance;
-    }
-
-    /**
-     * Delete an instance.
-     * 
-     * @param pid : name of the instance to delete
-     * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
-     */
-    public synchronized void deleted(String pid) {
-        m_instancesName.remove(pid);
-        final InstanceManager cm = (InstanceManager) m_componentInstances.remove(pid);
-        if (cm == null) {
-            return; // do nothing, the component does not exist !
-        } else {
-            cm.dispose();
-        }
-    }
-
-    /**
-     * Get the name of this factory.
-     * 
-     * @return the name of this factory
-     * @see org.apache.felix.ipojo.Factory#getName()
-     */
-    public String getName() {
-        if (m_factoryName != null) {
-            return m_factoryName;
-        } else if (m_typeName != null) {
-            return m_typeName;
-        } else {
-            return m_componentClassName;
-        }
-    }
-
-    /**
-     * Create of update an instance.
-     * 
-     * @param pid : name of the instance
-     * @param properties : configuration of the instance
-     * @throws ConfigurationException : if the configuration is not consistent
-     * for this component type
-     * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String,
-     * java.util.Dictionary)
-     */
-    public synchronized void updated(String pid, Dictionary properties) throws ConfigurationException {
-        final InstanceManager cm = (InstanceManager) m_componentInstances.get(pid);
-        if (cm == null) {
-            try {
-                properties.put("name", pid); // Add the name in the configuration
-                createComponentInstance(properties);
-            } catch (UnacceptableConfiguration e) {
-                m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
-                throw new ConfigurationException(properties.toString(), e.getMessage());
-            }
-        } else {
-            try {
-                properties.put("name", pid); // Add the name in the configuration
-                checkAcceptability(properties); // Test if the configuration is acceptable
-            } catch (UnacceptableConfiguration e) {
-                m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
-                throw new ConfigurationException(properties.toString(), e.getMessage());
-            }
-            cm.reconfigure(properties); // re-configure the component
-        }
-    }
-
-    /**
-     * Check if the given configuration is acceptable as a component instance
-     * configuration. This method checks that if all the configurable properties
-     * have a value.
-     * 
-     * @param conf : the configuration to check
-     * @return true when the configuration seems to be acceptable
-     */
-    public boolean isAcceptable(Dictionary conf) {
-        final PropertyDescription[] props = m_componentDesc.getProperties();
-        for (int i = 0; i < props.length; i++) {
-            final PropertyDescription pd = props[i];
-            // Failed if the props has no default value and the configuration
-            // does not push a value
-            if (pd.getValue() == null && conf.get(pd.getName()) == null) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Test is a configuration is acceptable for the factory.
-     * 
-     * @param conf : the configuration to test.
-     * @throws UnacceptableConfiguration : the configuration is not acceptable.
-     */
-    private void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration {
-        final PropertyDescription[] props = m_componentDesc.getProperties();
-        for (int i = 0; i < props.length; i++) {
-            final PropertyDescription pd = props[i];
-            // Failed if the props has no default value and the configuration
-            // does not push a value
-            if (pd.getValue() == null && conf.get(pd.getName()) == null) {
-                throw new UnacceptableConfiguration("The configuration does not contains the \"" + pd.getName() + "\" property");
-            }
-        }
-    }
-
-    /**
-     * Reconfigure an existing instance.
-     * 
-     * @param properties : the new configuration to push.
-     * @throws UnacceptableConfiguration : occurs if the new configuration is
-     * not consistent with the component type.
-     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
-     */
-    public void reconfigure(Dictionary properties) throws UnacceptableConfiguration {
-        if (properties == null || properties.get("name") == null) {
-            throw new UnacceptableConfiguration("The configuration does not contains the \"name\" property");
-        }
-        final String name = (String) properties.get("name");
-        ComponentInstance cm = null;
-        if (m_isComposite) {
-            cm = (CompositeManager) m_componentInstances.get(name);
-        } else {
-            cm = (InstanceManager) m_componentInstances.get(name);
-        }
-        if (cm == null) {
-            return; // The instance does not exist.
-        } else {
-            checkAcceptability(properties); // Test if the configuration is acceptable
-        }
-        cm.reconfigure(properties); // re-configure the component
-    }
     
     /**
      * Generate an instance name.
      * @return an non already used name
      */
-    private synchronized String generateName() {
+    protected synchronized String generateName() {
         String name = getName() + "-" + m_index;
         while (m_instancesName.contains(name)) {
             m_index = m_index + 1;
@@ -705,4 +816,243 @@
         }
         return name;
     }
+    
+    /**
+     * Return the bundle context.
+     * @return the Bundle Context.
+     */
+    protected BundleContext getBundleContext() {
+        return m_context;
+    }
+
+    /**
+     * Get the implementation class of the component type.
+     * 
+     * @return the name of the component-type implementation class.
+     */
+    protected String getComponentClassName() {
+        return m_componentClassName;
+    }
+
+    protected String getComponentTypeName() {
+        return m_typeName;
+    }
+
+    /**
+     * Compute factory properties.
+     * @return the properties.
+     */
+    protected Properties getProperties() {
+        final Properties props = new Properties();
+
+        props.put("component.class", m_componentClassName);
+       
+        props.put("factory.name", m_factoryName);
+        if (m_typeName != null) {
+            props.put("component.type", m_typeName);
+        }
+        
+        if (m_componentDesc != null) {
+            props.put("component.providedServiceSpecifications", m_componentDesc.getprovidedServiceSpecification());
+            props.put("component.properties", m_componentDesc.getProperties());
+            props.put("component.description", m_componentDesc);
+            props.put("component.desc", m_componentDesc.toString());
+        }
+        
+        // Add factory state
+        props.put("factory.state", "" + m_state);
+        
+        return props;
+    }
+    
+    /**
+     * Check if the given handler identifier and the service reference can match.
+     * @param hi : the handler identifier.
+     * @param ref : the service reference.
+     * @return true if the service reference can fulfill the handler requirement
+     */
+    protected boolean match(HandlerIdentifier hi, ServiceReference ref) {
+        String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);
+        String ns = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);
+        if (IPojoConfiguration.IPOJO_NAMESPACE.equals(ns)) {
+            ns = "";
+        }
+        return name.equals(hi.m_name) && ns.equals(hi.m_namespace); 
+    }
+
+    /**
+     * Return an handler object.
+     * 
+     * @param hi : handler to create.
+     * @param sc : service context in which create the handler (instance context).
+     * @return the Handler object.
+     */
+    private HandlerManager getHandlerInstance(HandlerIdentifier hi, ServiceContext sc) {
+        Factory factory = hi.getFactory();
+        try {
+            return (HandlerManager) factory.createComponentInstance(null, sc);
+        } catch (MissingHandlerException e) {
+            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed: " + e.getMessage());
+            return null;
+        } catch (UnacceptableConfiguration e) {
+            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());
+            return null;
+        } catch (org.apache.felix.ipojo.ConfigurationException e) {
+            m_logger.log(Logger.ERROR, "The configuration of the handler " + hi.getFullName() + " has failed (ConfigurationException): " + e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * Structure storing required handlers.
+     */
+    class HandlerIdentifier {
+        /**
+         * Factory to create this handler.
+         */
+        private Factory m_factory;
+        
+        /**
+         * Handler name.
+         */
+        private String m_name;
+        
+        /**
+         * Handler namespace.
+         */
+        private String m_namespace;
+        
+        /**
+         * Service Reference of the handler factory.
+         */
+        private ServiceReference m_reference;
+        
+        /**
+         * Constructor.
+         * @param n : handler name.
+         * @param ns : handler namespace.
+         */
+        public HandlerIdentifier(String n, String ns) {
+            m_name = n;
+            m_namespace = ns;
+        }
+        
+        /**
+         * Equals method.
+         * Two handlers are equals if they have same name and namespace or they share the same service reference.
+         * @param o : object to compare to the current object.
+         * @return : true if the two compared object are equals
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        public boolean equals(Object o) {
+            if (o instanceof HandlerIdentifier) {
+                return ((HandlerIdentifier) o).getName().equalsIgnoreCase(m_name) && ((HandlerIdentifier) o).getNamespace().equalsIgnoreCase(m_namespace);
+            } 
+            return false;
+        }
+        
+        /**
+         * Get the factory object used for this handler.
+         * The object is get when used for the first time.
+         * @return the factory object.
+         */
+        public Factory getFactory() {
+            if (m_reference == null) {
+                return null;
+            }
+            if (m_factory == null) {
+                m_factory = (Factory) m_tracker.getService(getReference());
+            }
+            return m_factory;
+        }
+        
+        /**
+         * Get the handler full name (namespace:name).
+         * @return the handler full name
+         */
+        public String getFullName() {
+            if ("".equals(m_namespace)) {
+                return IPojoConfiguration.IPOJO_NAMESPACE + ":" + m_name;
+            } else {
+                return m_namespace + ":" + m_name;
+            }
+        }
+        
+        public String getName() {
+            return m_name;
+        }
+        
+        public String getNamespace() {
+            return m_namespace;
+        }
+        
+        public ServiceReference getReference() {
+            return m_reference;
+        }
+        
+        /**
+         * Set the service reference.
+         * If the new service reference is null, it unget the used factory (if already get).
+         * @param ref : new service reference.
+         */
+        public void setReference(ServiceReference ref) {
+            if (m_reference != null) {
+                m_tracker.ungetService(m_reference);
+                m_factory = null;
+            }
+            m_reference = ref;
+        }
+    }
+
+    /**
+     * FactoryClassloader.
+     */
+    private class FactoryClassloader extends ClassLoader {
+
+        /**
+         * Map of defined classes [Name, Class Object].
+         */
+        private Map m_definedClasses = new HashMap();
+
+        /**
+         * The defineClass method.
+         * 
+         * @param name : name of the class
+         * @param b : the byte array of the class
+         * @param domain : the protection domain
+         * @return : the defined class.
+         * @throws Exception : if a problem is detected during the loading
+         */
+        public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
+            if (m_definedClasses.containsKey(name)) {
+                return (Class) m_definedClasses.get(name);
+            }
+            final Class c = super.defineClass(name, b, 0, b.length, domain);
+            m_definedClasses.put(name, c);
+            return c;
+        }
+
+        /**
+         * Return the URL of the asked resource.
+         * 
+         * @param arg : the name of the resource to find.
+         * @return the URL of the resource.
+         * @see java.lang.ClassLoader#getResource(java.lang.String)
+         */
+        public URL getResource(String arg) {
+            return m_context.getBundle().getResource(arg);
+        }
+
+        /**
+         * Load the class.
+         * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+         * @param name : the name of the class
+         * @param resolve : should be the class resolve now ?
+         * @return : the loaded class
+         * @throws ClassNotFoundException : the class to load is not found
+         */
+        protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+            return m_context.getBundle().loadClass(name);
+        }
+    }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
index 31cc863..9b6c574 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
@@ -20,13 +20,11 @@
 
 import java.util.Dictionary;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.osgi.framework.BundleContext;
 
 /**
  * The component instance class manages one instance of a component type.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public interface ComponentInstance {
@@ -78,13 +76,6 @@
     int getState();
 
     /**
-     * Return component-type description of this instance.
-     * @return the component type information. Each handler can participate to
-     * the component description.
-     */
-    ComponentDescription getComponentDescription();
-
-    /**
      * Return the instance description.
      * @return the instance description of the current instance
      */
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java
new file mode 100644
index 0000000..2b6bdf5
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java
@@ -0,0 +1,404 @@
+/* 

+ * 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;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Dictionary;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.architecture.ComponentDescription;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.util.Logger;

+import org.apache.felix.ipojo.util.Tracker;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Constants;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * The component factory manages component instance objects. This management

+ * consist in creating and managing component instance build with the component

+ * factory. This class could export Factory and ManagedServiceFactory services.

+ * 

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class CompositeFactory extends ComponentFactory implements Factory {

+

+    /**

+     * Service Registration of this factory (Factory & ManagedServiceFactory).

+     */

+    private ServiceRegistration m_sr;

+

+    /**

+     * Create a composite factory.

+     * @param bc : bundle context

+     * @param cm : metadata of the component to create

+     */

+    public CompositeFactory(BundleContext bc, Element cm) {

+        super(bc, cm);

+    }

+    

+    /**

+     * Check if the metadata are well formed.

+     * @param cm : metadata

+     * @return true if the metadata are correct.

+     * @see org.apache.felix.ipojo.ComponentFactory#check(org.apache.felix.ipojo.metadata.Element)

+     */

+    public boolean check(Element cm) {

+     // Get the name

+        if (cm.containsAttribute("name")) {

+            m_typeName = cm.getAttribute("name");

+            return true;

+        } else {

+            System.err.println("A composite needs a name");

+            return false;

+        }

+    }

+    

+    /**

+     * Check if the given handler identifier can be fulfilled by the given service reference.

+     * @param hi : handler identifier.

+     * @param ref : service reference.

+     * @return true if the service reference can fulfill the given handler identifier

+     * @see org.apache.felix.ipojo.ComponentFactory#match(org.apache.felix.ipojo.ComponentFactory.HandlerIdentifier, org.osgi.framework.ServiceReference)

+     */

+    public boolean match(HandlerIdentifier hi, ServiceReference ref) {

+        String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);

+        String ns = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);

+        String type = (String) ref.getProperty(Handler.HANDLER_TYPE_PROPERTY);

+        

+        if ("composite".equals(type)) {

+            if (IPojoConfiguration.IPOJO_NAMESPACE.equals(ns)) {

+                ns = "";

+            }

+            return name.equals(hi.getName()) && ns.equals(hi.getNamespace()); 

+        } else {

+            return false;

+        }

+    }

+    

+    /**

+     * Compute required handlers.

+     */

+    protected void computeRequiredHandlers() {

+        Element[] elems = m_componentMetadata.getElements();

+        for (int i = 0; i < elems.length; i++) {

+            Element current = elems[i]; 

+            HandlerIdentifier hi = new HandlerIdentifier(current.getName(), current.getNameSpace());

+            if (! m_handlerIdentifiers.contains(hi)) { m_handlerIdentifiers.add(hi); }

+        }

+        

+        // Add architecture if needed

+        if (m_componentMetadata.containsAttribute("architecture") && m_componentMetadata.getAttribute("architecture").equalsIgnoreCase("true")) {

+            HandlerIdentifier hi = new HandlerIdentifier("architecture", "");

+            if (! m_handlerIdentifiers.contains(hi)) { m_handlerIdentifiers.add(hi); }

+        }

+    }

+    

+    /**

+     * Stop all the instance managers.

+     */

+    public synchronized void stop() {

+        m_tracker.close();

+        

+        final Collection col = m_componentInstances.values();

+        final Iterator it = col.iterator();

+        while (it.hasNext()) {

+            CompositeManager ci = (CompositeManager) it.next();

+            if (ci.getState() != ComponentInstance.DISPOSED) {

+                ci.kill();

+            }

+            m_instancesName.remove(ci.getInstanceName());

+        }

+        

+        m_componentInstances.clear();

+        if (m_sr != null) { 

+            m_sr.unregister();

+            m_sr = null;

+        }

+        m_tracker = null;

+        m_componentDesc = null;

+        m_state = INVALID;

+    }

+

+    /**

+     * Start all the instance managers.

+     */

+    public synchronized void start() {

+        if (m_componentDesc != null) { // Already started.

+            return;

+        } 

+        try {

+            String filter = "(&(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")"

+                    + "(" + Handler.HANDLER_NAME_PROPERTY + "=*)" + "(" + Handler.HANDLER_NAMESPACE_PROPERTY + "=*)" /* Look only for handlers */

+                    + "(" + Handler.HANDLER_TYPE_PROPERTY + "=" + CompositeHandler.HANDLER_TYPE + ")" 

+                    + "(factory.state=1)"

+                    + ")";

+            m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);

+            m_tracker.open();

+            

+        } catch (InvalidSyntaxException e) {

+            m_logger.log(Logger.ERROR, "A factory filter is not valid: " + e.getMessage());

+            return;

+        }

+        

+        computeFactoryState();

+        

+        // Check if the factory should be exposed

+        if (m_factoryName == null) { return; }

+        

+        // Exposition of the factory service

+        m_sr = m_context.registerService(new String[] { Factory.class.getName() }, this, getProperties());

+    }

+    

+    

+    /**

+     * Compute factory service properties.

+     * @return the factory service properties

+     * @see org.apache.felix.ipojo.ComponentFactory#getProperties()

+     */

+    protected Properties getProperties() {

+        final Properties props = new Properties();

+        

+        if (m_componentDesc != null) {

+            props.put("component.providedServiceSpecifications", m_componentDesc.getprovidedServiceSpecification());

+            props.put("component.properties", m_componentDesc.getProperties());

+            props.put("component.description", m_componentDesc);

+            props.put("component.desc", m_componentDesc.toString());

+        }

+        

+        // Add factory state

+        props.put("factory.state", "" + m_state);

+        

+        props.put("factory.name", m_factoryName);

+        props.put("component.type", m_typeName);

+        

+        return props;

+    }

+

+

+    /**

+     * Create an instance. The given configuration needs to contain the 'name'

+     * property.

+     * @param configuration : configuration of the created instance.

+     * @return the created component instance.

+     * @throws UnacceptableConfiguration : occurs if the given configuration is

+     * not consistent with the component type of this factory.

+     * @throws MissingHandlerException  : occurs if an handler is unavailable when the instance is created.

+     * @throws ConfigurationException  : occurs if an error occurs during the instance configuration.

+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)

+     */

+    public synchronized ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {

+        return createComponentInstance(configuration, null);

+    }

+

+    /**

+     * Create an instance. The given configuration needs to contain the 'name'

+     * property.

+     * @param configuration : configuration of the created instance.

+     * @param serviceContext : the service context to push for this instance.

+     * @return the created component instance.

+     * @throws UnacceptableConfiguration : occurs if the given configuration is

+     * not consistent with the component type of this factory.

+     * @throws MissingHandlerException : occurs when an handler is unavailable when creating the instance.

+     * @throws ConfigurationException  : occurs when the instance configuration failed.

+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)

+     */

+    public synchronized ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {

+        if (m_state == INVALID) {

+            throw new MissingHandlerException(getMissingHandlers());

+        }

+        

+        if (configuration == null) {

+            configuration = new Properties();

+        }

+        

+        try {

+            checkAcceptability(configuration);

+        } catch (UnacceptableConfiguration e) {

+            m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());

+            throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage());

+        }

+

+        

+        String in = null;

+        if (configuration.get("name") != null) {

+            in = (String) configuration.get("name");

+        } else {

+            in = generateName();

+            configuration.put("name", in);

+        }

+        

+        if (m_instancesName.contains(in)) {

+            throw new UnacceptableConfiguration("Name already used : " + in + "(" + m_instancesName + ")");

+        } else {

+            m_instancesName.add(in);

+        }

+

+        BundleContext context = null;

+        if (serviceContext == null) {

+            context = new IPojoContext(m_context);

+        } else {

+            context = new IPojoContext(m_context, serviceContext);

+        }

+        ComponentInstance instance = null;

+        List handlers = new ArrayList();

+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {

+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);

+            handlers.add(getHandlerInstance(hi, serviceContext));

+        }

+       

+        final CompositeManager inst = new CompositeManager(this, context, (HandlerManager[]) handlers.toArray(new HandlerManager[0]));

+        inst.configure(m_componentMetadata, configuration);

+        instance = inst;

+

+        m_componentInstances.put(in, instance);

+        instance.start();

+        return instance;

+    }

+

+    /**

+     * Reconfigure an existing instance.

+     * @param properties : the new configuration to push.

+     * @throws UnacceptableConfiguration : occurs if the new configuration is

+     * not consistent with the component type.

+     * @throws MissingHandlerException : occurs when an handler is unavailable when creating the instance.

+     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)

+     */

+    public synchronized void reconfigure(Dictionary properties) throws UnacceptableConfiguration, MissingHandlerException {

+        if (properties == null || properties.get("name") == null) {

+            throw new UnacceptableConfiguration("The configuration does not contains the \"name\" property");

+        }

+        final String name = (String) properties.get("name");

+        

+        ComponentInstance cm = (CompositeManager) m_componentInstances.get(name);

+        

+        if (cm == null) {

+            return; // The instance does not exist.

+        }

+        

+        cm.reconfigure(properties); // re-configure the component

+    }

+    

+    /**

+     * Compute factory state.

+     */

+    protected void computeFactoryState() {

+        boolean isValid = true;

+        for (int i = 0; isValid && i < m_handlerIdentifiers.size(); i++) {

+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);

+            isValid = hi.getReference() != null;

+        }

+

+        if (isValid && m_componentDesc == null) {

+            try {

+                computeDescription();

+            } catch (org.apache.felix.ipojo.ConfigurationException e) {

+                m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());

+                stop();

+                return;

+            }

+        }

+

+        if (isValid && m_state == INVALID) {

+            m_state = VALID;

+            if (m_sr != null) {

+                m_sr.setProperties(getProperties());

+            }

+            for (int i = 0; i < m_listeners.size(); i++) {

+                ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, VALID);

+            }

+            return;

+        }

+

+        if (!isValid && m_state == VALID) {

+            m_state = INVALID;

+

+            final Collection col = m_componentInstances.values();

+            final Iterator it = col.iterator();

+            while (it.hasNext()) {

+                CompositeManager ci = (CompositeManager) it.next();

+                ci.kill();

+                m_instancesName.remove(ci.getInstanceName());

+            }

+

+            m_componentInstances.clear();

+

+            if (m_sr != null) {

+                m_sr.setProperties(getProperties());

+            }

+

+            for (int i = 0; i < m_listeners.size(); i++) {

+                ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);

+            }

+            return;

+        }

+

+    }

+

+    /**

+     * Compute component type description.

+     * @throws ConfigurationException : if one handler has rejected the configuration.

+     * @see org.apache.felix.ipojo.ComponentFactory#computeDescription()

+     */

+    public void computeDescription() throws ConfigurationException {

+        List l = new ArrayList();

+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {

+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);

+            l.add(hi.getFullName());

+        }

+        

+        m_componentDesc = new ComponentDescription(getName(), "composite", m_state, l, getMissingHandlers(), m_context.getBundle().getBundleId());

+       

+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {

+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);

+            HandlerManager hm = getHandlerInstance(hi, null);

+            hm.getHandler();

+            Handler ch =  hm.getHandler();

+            ch.initializeComponentFactory(m_componentDesc, m_componentMetadata);

+            ((Pojo) ch).getComponentInstance().dispose();

+        }

+    }

+    

+    /**

+     * Get a composite handler object for the given handler identifier.

+     * @param handler : the handler identifier.

+     * @param sc : the service context in which creating the handler.

+     * @return the composite handler object or null if not found.

+     */

+    private HandlerManager getHandlerInstance(HandlerIdentifier handler, ServiceContext sc) {

+        Factory factory = (Factory) m_context.getService(handler.getReference());

+        try {

+            return (HandlerManager) factory.createComponentInstance(null, sc);

+        } catch (MissingHandlerException e) {

+            m_logger.log(Logger.ERROR, "The creation of the composite handler " + handler.getFullName() + " has failed: " + e.getMessage());

+            return null;

+        } catch (UnacceptableConfiguration e) {

+            m_logger.log(Logger.ERROR, "The creation of the composite handler " + handler.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());

+            return null;

+        } catch (ConfigurationException e) {

+            m_logger.log(Logger.ERROR, "The creation of the composite handler " + handler.getFullName() + " has failed (ConfigurationException): " + e.getMessage());

+            return null;

+        }

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
index 5307d9f..7ac7487 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
@@ -18,10 +18,6 @@
  */
 package org.apache.felix.ipojo;
 
-import java.util.Dictionary;
-
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Element;
 
 /**
  * Composite Handler Abstract Class. An composite handler need implements these
@@ -29,58 +25,60 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public abstract class CompositeHandler {
-
+public abstract class CompositeHandler extends Handler {
+    
     /**
-     * Configure the handler.
-     * 
-     * @param im : the instance manager
-     * @param metadata : the metadata of the component
-     * @param configuration : the instance configuration
+     * Composite Handler type.
      */
-    public abstract void configure(CompositeManager im, Element metadata, Dictionary configuration);
-
+    public static final String HANDLER_TYPE = "composite";
+    
     /**
-     * Stop the handler : stop the management.
+     * Reference on the composite manager.
      */
-    public abstract void stop();
-
+    private CompositeManager m_manager;
+    
     /**
-     * Start the handler : start the management.
+     * Set the manager.
+     * This method me be called only once time.
+     * @param cm : the composite manager.
      */
-    public abstract void start();
-
-    /**
-     * Is the actual state valid for this handler ?
-     * 
-     * @return true is the state seems valid for the handler
-     */
-    public boolean isValid() {
-        return true;
+    public final void attach(ComponentInstance cm) {
+        m_manager = (CompositeManager) cm;
     }
-
-    /**
-     * This method is called when the component state changed.
-     * 
-     * @param state : the new state
-     */
-    public void stateChanged(int state) {
+    
+    public final CompositeManager getCompositeManager() {
+        return m_manager;
     }
-
+        
     /**
-     * Return the description of the handler.
-     * @return the description of the handler.
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
      */
-    public HandlerDescription getDescription() {
-        return new HandlerDescription(this.getClass().getName(), isValid());
+    public void log(int level, String message) {
+        m_manager.getFactory().getLogger().log(level, message);
     }
-
+    
     /**
-     * The instance is reconfiguring.
-     * 
-     * @param configuration : New instance configuration.
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
+     * @param ex : exception to attach to the message
      */
-    public void reconfigure(Dictionary configuration) {
+    public void log(int level, String message, Throwable ex) {
+        m_manager.getFactory().getLogger().log(level, message, ex);
     }
-
+    
+    /**
+     * Get a plugged handler of the same container.
+     * This method must be call only in the start method (or after).
+     * In the configure method, this method can not return a consistent
+     * result as all handlers are not plugged. 
+     * @param name : name of the handler to find (class name). 
+     * @return the composite handler object or null if the handler is not found.
+     */
+    public final Handler getHandler(String name) {
+        return m_manager.getCompositeHandler(name);
+    }
+    
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
index 7802473..8658764 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
@@ -18,14 +18,14 @@
  */
 package org.apache.felix.ipojo;
 
+import java.util.ArrayList;
 import java.util.Dictionary;
+import java.util.List;
 
 import org.apache.felix.ipojo.architecture.Architecture;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.composite.CompositeServiceContext;
 import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
@@ -37,17 +37,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class CompositeManager implements ComponentInstance {
-
-    /**
-     * Parent factory (ComponentFactory).
-     */
-    private ComponentFactory m_factory;
-
-    /**
-     * Name of the component instance.
-     */
-    private String m_name;
+public class CompositeManager implements ComponentInstance, InstanceStateListener {
 
     /**
      * The context of the component.
@@ -55,44 +45,73 @@
     private BundleContext m_context;
 
     /**
-     * Composite Handler list.
+     * Parent factory (ComponentFactory).
      */
-    private CompositeHandler[] m_handlers = new CompositeHandler[0];
+    private ComponentFactory m_factory;
 
     /**
-     * Component state (STOPPED at the beginning).
+     * Composite Handler list.
      */
-    private int m_state = STOPPED;
-    
+    private HandlerManager[] m_handlers = new HandlerManager[0];
+
     /**
      * Instance State Listener List.
      */
-    private InstanceStateListener[] m_instanceListeners = new InstanceStateListener[0];
-
-
-    /**
-     * Component type information.
-     */
-    private ComponentDescription m_componentDesc;
+    private List m_instanceListeners = new ArrayList();
 
     /**
      * Internal service context of the composition.
      */
     private CompositeServiceContext m_internalContext;
+    
+    /**
+     * Name of the component instance.
+     */
+    private String m_name;
 
-    // Constructor
+    /**
+     * Component state (STOPPED at the beginning).
+     */
+    private int m_state = STOPPED;
+
     /**
      * Construct a new Component Manager.
-     * 
      * @param factory : the factory managing the instance manager
      * @param bc : the bundle context to give to the instance
+     * @param handlers : the handlers to plug
      */
-    public CompositeManager(ComponentFactory factory, BundleContext bc) {
+    public CompositeManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
         m_factory = factory;
         m_context = bc;
         // Initialize the service context.
         m_internalContext = new CompositeServiceContext(m_context, this);
-        m_factory.getLogger().log(Logger.INFO, "[Bundle " + m_context.getBundle().getBundleId() + "] Create an instance manager from the factory " + m_factory);
+        m_handlers = handlers;
+    }
+
+    /**
+     * Plug the given handler to the current container.
+     * @param h : the handler to plug.
+     */
+    public synchronized void addCompositeHandler(HandlerManager h) {
+        if (m_handlers.length > 0) {
+            HandlerManager[] newInstances = new HandlerManager[m_handlers.length + 1];
+            System.arraycopy(m_handlers, 0, newInstances, 0, m_handlers.length);
+            newInstances[m_handlers.length] = h;
+            m_handlers = newInstances;
+        } else {
+            m_handlers = new HandlerManager[] { h };
+        }
+    }
+
+    /**
+     * Add an instance to the created instance list.
+     * @param listener : the instance state listener to add.
+     * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
+     */
+    public void addInstanceStateListener(InstanceStateListener listener) {
+        synchronized (m_instanceListeners) {
+            m_instanceListeners.add(listener);
+        }
     }
 
     /**
@@ -101,76 +120,89 @@
      * 
      * @param cm : the component type metadata
      * @param configuration : the configuration of the instance
+     * @throws ConfigurationException : occurs when the component type are incorrect.
      */
-    public void configure(Element cm, Dictionary configuration) {
-        // Stop all previous registered handler
-        if (m_handlers.length != 0) {
-            stop();
-        }
-
-        // Clear the handler list
-        m_handlers = new CompositeHandler[0];
-
-        // ComponentInfo initialization
-        m_componentDesc = new ComponentDescription(m_factory.getName());
-
+    public void configure(Element cm, Dictionary configuration) throws ConfigurationException {        
         // Add the name
         m_name = (String) configuration.get("name");
-
+        
         // Create the standard handlers and add these handlers to the list
-        for (int i = 0; i < IPojoConfiguration.INTERNAL_COMPOSITE_HANDLERS.length; i++) {
-            // Create a new instance
-            try {
-                CompositeHandler h = (CompositeHandler) IPojoConfiguration.INTERNAL_COMPOSITE_HANDLERS[i].newInstance();
-                h.configure(this, cm, configuration);
-            } catch (InstantiationException e) {
-                m_factory.getLogger().log(Logger.ERROR,
-                        "[" + m_name + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
-            } catch (IllegalAccessException e) {
-                m_factory.getLogger().log(Logger.ERROR,
-                        "[" + m_name + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
-            }
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].init(this, cm, configuration);
         }
+    }
+    
+    /** 
+     * Dispose the instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
+     */
+    public void dispose() {
+        if (m_state > STOPPED) { stop(); }
+        
+        for (int i = 0; i < m_instanceListeners.size(); i++) {
+            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
+        }
+        
+        m_factory.disposed(this);
 
-        // Look for namespaces
-        for (int i = 0; i < cm.getNamespaces().length; i++) {
-            if (!cm.getNamespaces()[i].equals("")) {
-                // It is not an internal handler, try to load it
-                try {
-                    Class c = m_context.getBundle().loadClass(cm.getNamespaces()[i]);
-                    CompositeHandler h = (CompositeHandler) c.newInstance();
-                    h.configure(this, cm, configuration);
-                } catch (ClassNotFoundException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                } catch (InstantiationException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                } catch (IllegalAccessException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                }
-            }
+        // Cleaning
+        m_state = DISPOSED;
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].dispose();
         }
+        m_handlers = new HandlerManager[0];
+        m_instanceListeners.clear();
     }
 
     /**
-     * Return the component type description of this instance.
-     * @return the component type information.
-     * @see org.apache.felix.ipojo.ComponentInstance#getComponentDescription()
+     * Return a specified handler.
+     * @param name : class name of the handler to find
+     * @return : the handler, or null if not found
      */
-    public ComponentDescription getComponentDescription() {
-        return m_componentDesc;
+    public CompositeHandler getCompositeHandler(String name) {
+        for (int i = 0; i < m_handlers.length; i++) {
+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getFactory();
+            if (fact.getHandlerName().equals(name) || fact.getComponentClassName().equals(name)) {
+                return (CompositeHandler) m_handlers[i].getHandler();
+            }
+        }
+        return null;
     }
 
     /**
+     * Get the bundle context used by this instance.
+     * @return the parent context of the instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#getContext()
+     */
+    public BundleContext getContext() {
+        return m_context;
+    }
+
+    /**
+     * Get the factory which create this instance.
+     * @return the factory of the component
+     * @see org.apache.felix.ipojo.ComponentInstance#getFactory()
+     */
+    public ComponentFactory getFactory() {
+        return m_factory;
+    }
+    
+    /**
+     * Get the global bundle context.
+     * @return the global bundle context.
+     */
+    public BundleContext getGlobalContext() {
+        IPojoContext c = (IPojoContext) m_context;
+        return c.getGlobalContext();
+    }
+    
+    /**
      * Return the instance description of this instance.
      * @return the instance description.
      * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
      */
-    public synchronized InstanceDescription getInstanceDescription() {
-        int componentState = getState();
-        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_componentDesc);
+    public InstanceDescription getInstanceDescription() {
+        InstanceDescription instanceDescription = new InstanceDescription(m_name, m_state, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
         CompositeHandler[] handlers = getRegistredCompositeHandlers();
         for (int i = 0; i < handlers.length; i++) {
             instanceDescription.addHandler(handlers[i].getDescription());
@@ -194,144 +226,43 @@
     }
 
     /**
+     * Get the instance name.
+     * @return the instance name
+     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
+     */
+    public String getInstanceName() {
+        return m_name;
+    }
+
+    /**
+     * Get the parent service context.
+     * @return the parent service context.
+     */
+    public ServiceContext getParentServiceContext() {
+        IPojoContext c = (IPojoContext) m_context;
+        return c.getServiceContext();
+    }
+
+    /**
      * REturn the list of handlers plugged on this instance.
      * @return the list of the registered handlers.
      */
     public CompositeHandler[] getRegistredCompositeHandlers() {
-        return m_handlers;
-    }
-
-    /**
-     * Return a specified handler.
-     * 
-     * @param name : class name of the handler to find
-     * @return : the handler, or null if not found
-     */
-    public CompositeHandler getCompositeHandler(String name) {
+        CompositeHandler[] h = new CompositeHandler[m_handlers.length];
         for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i].getClass().getName().equalsIgnoreCase(name)) {
-                return m_handlers[i];
-            }
+            h[i] = (CompositeHandler) m_handlers[i].getHandler();
         }
-        return null;
-    }
-
-    // ===================== Lifecycle management =====================
-
-    /**
-     * Start the instance manager.
-     */
-    public void start() {
-        if (m_state != STOPPED) {
-            return;
-        } // Instance already started
-
-        // Start all the handlers
-        m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] Start the instance manager with " + m_handlers.length + " handlers");
-
-        // The new state of the component is UNRESOLVED
-        m_state = INVALID;
-
-        m_internalContext.start(); // Turn on the factory tracking
-
-        for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].start();
-        }
-
-        // Defines the state of the component :
-        checkInstanceState();
-    }
-
-    /**
-     * Stop the instance manager.
-     */
-    public void stop() {
-        if (m_state == STOPPED) {
-            return;
-        } // Instance already stopped
-
-        setState(INVALID);
-        // Stop all the handlers
-        for (int i = m_handlers.length - 1; i > -1; i--) {
-            m_handlers[i].stop();
-        }
-
-        m_internalContext.stop(); // Turn off the factory tracking
-        m_state = STOPPED;
-        
-        for (int i = 0; i < m_instanceListeners.length; i++) {
-            m_instanceListeners[i].stateChanged(this, STOPPED);
-        }
-    }
-    
-    /** 
-     * Dispose the instance.
-     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
-     */
-    public void dispose() {
-        if (m_state > STOPPED) {
-            stop();
-        }
-        
-        for (int i = 0; i < m_instanceListeners.length; i++) {
-            m_instanceListeners[i].stateChanged(this, DISPOSED);
-        }
-        
-        m_factory.disposed(this);
-
-        // Cleaning
-        m_state = DISPOSED;
-        m_handlers = new CompositeHandler[0];
-        m_instanceListeners = new InstanceStateListener[0];
+        return h;
     }
     
     /**
-     * Kill the current instance.
-     * Only the factory of this instance can call this method.
+     * Get the internal service context of this instance.
+     * @return the internal service context.
      */
-    protected void kill() {
-        if (m_state > STOPPED) {
-            stop();
-        }
-        
-        for (int i = 0; i < m_instanceListeners.length; i++) {
-            m_instanceListeners[i].stateChanged(this, DISPOSED);
-        }
-
-        // Cleaning
-        m_state = DISPOSED;
-        m_handlers = new CompositeHandler[0];
-        m_instanceListeners = new InstanceStateListener[0];
+    public ServiceContext getServiceContext() {
+        return m_internalContext;
     }
-
-    /**
-     * Set the state of the component. 
-     * Ff the state changed call the stateChanged(int) method on the handlers.
-     * @param state : new state
-     */
-    public void setState(int state) {
-        if (m_state != state) {
-
-            // Log the state change
-            if (state == INVALID) {
-                m_factory.getLogger().log(Logger.INFO, "[" + m_name + "]  State -> INVALID");
-            }
-            if (state == VALID) {
-                m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] State -> VALID");
-            }
-
-            // The state changed call the handler stateChange method
-            m_state = state;
-            for (int i = m_handlers.length - 1; i > -1; i--) {
-                m_handlers[i].stateChanged(state);
-            }
-            
-            for (int i = 0; i < m_instanceListeners.length; i++) {
-                m_instanceListeners[i].stateChanged(this, state);
-            }
-        }
-    }
-
+    
     /**
      * Get the actual state of the instance.
      * @return the actual state of the instance
@@ -340,167 +271,14 @@
     public int getState() {
         return m_state;
     }
-
+    
     /**
      * Check if the instance is started.
      * @return true if the instance is started.
      * @see org.apache.felix.ipojo.ComponentInstance#isStarted()
      */
     public boolean isStarted() {
-        return m_state != STOPPED;
-    }
-    
-    /**
-     * Add an instance to the created instance list.
-     * @param listener : the instance state listener to add.
-     * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
-     */
-    public void addInstanceStateListener(InstanceStateListener listener) {
-        for (int i = 0; (m_instanceListeners != null) && (i < m_instanceListeners.length); i++) {
-            if (m_instanceListeners[i] == listener) {
-                return;
-            }
-        }
-
-        if (m_instanceListeners.length > 0) {
-            InstanceStateListener[] newInstances = new InstanceStateListener[m_instanceListeners.length + 1];
-            System.arraycopy(m_instanceListeners, 0, newInstances, 0, m_instanceListeners.length);
-            newInstances[m_instanceListeners.length] = listener;
-            m_instanceListeners = newInstances;
-        } else {
-            m_instanceListeners = new InstanceStateListener[] { listener };
-        }
-    }
-    
-    /**
-     * Remove an instance state listener.
-     * @param listener : the listener to remove
-     * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
-     */
-    public void removeInstanceStateListener(InstanceStateListener listener) {
-        int idx = -1;
-        for (int i = 0; i < m_instanceListeners.length; i++) {
-            if (m_instanceListeners[i] == listener) {
-                idx = i;
-                break;
-            }
-        }
-        
-        if (idx >= 0) {
-            if ((m_instanceListeners.length - 1) == 0) {
-                m_instanceListeners = new InstanceStateListener[0];
-            } else {
-                InstanceStateListener[] newInstances = new InstanceStateListener[m_instanceListeners.length - 1];
-                System.arraycopy(m_instanceListeners, 0, newInstances, 0, idx);
-                if (idx < newInstances.length) {
-                    System.arraycopy(m_instanceListeners, idx + 1, newInstances, idx, newInstances.length - idx);
-                }
-                m_instanceListeners = newInstances;
-            }
-        }
-    }
-
-    // ===================== end Lifecycle management =====================
-
-    // ================== Class & Instance management ===================
-
-    /**
-     * Get the factory which create this instance.
-     * @return the factory of the component
-     * @see org.apache.felix.ipojo.ComponentInstance#getFactory()
-     */
-    public ComponentFactory getFactory() {
-        return m_factory;
-    }
-
-    // ======================== Handlers Management ======================
-
-    /**
-     * Register the given handler to the current instance manager.
-     * 
-     * @param h : the handler to register
-     */
-    public void register(CompositeHandler h) {
-        for (int i = 0; (m_handlers != null) && (i < m_handlers.length); i++) {
-            if (m_handlers[i] == h) {
-                return;
-            }
-        }
-
-        if (m_handlers != null) {
-            CompositeHandler[] newList = new CompositeHandler[m_handlers.length + 1];
-            System.arraycopy(m_handlers, 0, newList, 0, m_handlers.length);
-            newList[m_handlers.length] = h;
-            m_handlers = newList;
-        }
-    }
-
-    /**
-     * Unregister the given handler.
-     * 
-     * @param h : the handler to unregister
-     */
-    public void unregister(CompositeHandler h) {
-        int idx = -1;
-        for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i] == h) {
-                idx = i;
-                break;
-            }
-        }
-
-        if (idx >= 0) {
-            if ((m_handlers.length - 1) == 0) {
-                m_handlers = new CompositeHandler[0];
-            } else {
-                CompositeHandler[] newList = new CompositeHandler[m_handlers.length - 1];
-                System.arraycopy(m_handlers, 0, newList, 0, idx);
-                if (idx < newList.length) {
-                    System.arraycopy(m_handlers, idx + 1, newList, idx, newList.length - idx);
-                }
-                m_handlers = newList;
-            }
-        }
-    }
-
-    /**
-     * Get the bundle context used by this instance.
-     * @return the parent context of the instance.
-     * @see org.apache.felix.ipojo.ComponentInstance#getContext()
-     */
-    public BundleContext getContext() {
-        return m_context;
-    }
-
-    /**
-     * Check the state of all handlers.
-     */
-    public void checkInstanceState() {
-        m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] Check the instance state");
-        boolean isValid = true;
-        for (int i = 0; i < m_handlers.length; i++) {
-            boolean b = m_handlers[i].isValid();
-            isValid = isValid && b;
-        }
-
-        // Update the component state if necessary
-        if (!isValid && m_state == VALID) {
-            // Need to update the state to UNRESOLVED
-            setState(INVALID);
-            return;
-        }
-        if (isValid && m_state == INVALID) {
-            setState(VALID);
-        }
-    }
-
-    /**
-     * Get the instance name.
-     * @return the instance name
-     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
-     */
-    public String getInstanceName() {
-        return m_name;
+        return m_state > STOPPED;
     }
 
     /**
@@ -515,28 +293,136 @@
     }
 
     /**
-     * Get the internal service context of this instance.
-     * @return the internal service context.
+     * Remove an instance state listener.
+     * @param listener : the listener to remove
+     * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
-    public ServiceContext getServiceContext() {
-        return m_internalContext;
+    public void removeInstanceStateListener(InstanceStateListener listener) {
+        synchronized (m_instanceListeners) {
+            m_instanceListeners.remove(listener);
+        }
     }
 
     /**
-     * Get the global bundle context.
-     * @return the global bundle context.
+     * Set the state of the component. 
+     * if the state changed call the stateChanged(int) method on the handlers.
+     * @param state : new state
      */
-    public BundleContext getGlobalContext() {
-        IPojoContext c = (IPojoContext) m_context;
-        return c.getGlobalContext();
+    public void setState(int state) {
+        if (m_state != state) {
+
+            // The state changed call the handler stateChange method
+            m_state = state;
+            for (int i = m_handlers.length - 1; i > -1; i--) {
+                m_handlers[i].getHandler().stateChanged(state);
+            }
+            
+            for (int i = 0; i < m_instanceListeners.size(); i++) {
+                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
+            }
+        }
+    }
+
+    /**
+     * Start the instance manager.
+     */
+    public synchronized void start() {
+        if (m_state > STOPPED) {
+            return;
+        } // Instance already started
+
+
+        // The new state of the component is UNRESOLVED
+        m_state = INVALID;
+
+        m_internalContext.start(); // Turn on the factory tracking
+
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].start();
+            m_handlers[i].addInstanceStateListener(this);
+        }
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i].getState() != VALID) {
+                setState(INVALID);
+                return;
+            }
+        }
+        setState(VALID);
+        
+    }
+
+    /**
+     * State Change listener callback.
+     * This method is notified at each time a plugged handler becomes invalid.
+     * @param instance : changing instance 
+     * @param newState : new state
+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
+     */
+    public synchronized void stateChanged(ComponentInstance instance, int newState) {
+        if (m_state <= STOPPED) { return; }
+     
+        // Update the component state if necessary
+        if (newState == INVALID && m_state == VALID) {
+            // Need to update the state to UNRESOLVED
+            setState(INVALID);
+            return;
+        }
+        if (newState == VALID && m_state == INVALID) {
+            // An handler becomes valid => check if all handlers are valid
+            boolean isValid = true;
+            for (int i = 0; i < m_handlers.length; i++) {
+                isValid = isValid && m_handlers[i].getState() == VALID;
+            }
+            
+            if (isValid) { setState(VALID); }
+        }
+        if (newState == DISPOSED) {
+            kill();
+        }
+    }
+
+    /**
+     * Stop the instance manager.
+     */
+    public synchronized void stop() {
+        if (m_state <= STOPPED) {
+            return;
+        } // Instance already stopped
+
+        setState(INVALID);
+        // Stop all the handlers
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].removeInstanceStateListener(this);
+            m_handlers[i].stop();
+        }
+
+        m_internalContext.stop(); // Turn off the factory tracking
+        m_state = STOPPED;
+        
+        for (int i = 0; i < m_instanceListeners.size(); i++) {
+            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+        }
     }
     
     /**
-     * Get the parent service context.
-     * @return the parent service context.
+     * Kill the current instance.
+     * Only the factory of this instance can call this method.
      */
-    public ServiceContext getParentServiceContext() {
-        IPojoContext c = (IPojoContext) m_context;
-        return c.getServiceContext();
+    protected synchronized void kill() {
+        if (m_state > STOPPED) { stop(); }
+        
+        for (int i = 0; i < m_instanceListeners.size(); i++) {
+            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
+        }
+
+        // Cleaning
+        m_state = DISPOSED;
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].dispose();
+        }
+        m_handlers = new HandlerManager[0];
+        m_instanceListeners.clear();
     }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
new file mode 100644
index 0000000..5f0c2c7
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
@@ -0,0 +1,62 @@
+/* 

+ * 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;

+

+/**

+ * Configuration Exception.

+ * This exception occurs when component metadata are not correct.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class ConfigurationException extends Exception {

+    

+    /**

+     * Serialization Id.

+     */

+    private static final long serialVersionUID = 1L;

+

+    /**

+     * Message.

+     */

+    private String m_message;

+    

+    /**

+     * Component Type on which the error occurs.

+     */

+    private String m_type;

+    

+    /**

+     * Constructor.

+     * @param mes : message

+     * @param typ : component type

+     */

+    public ConfigurationException(String mes, String typ) {

+        m_type = typ;

+        m_message = mes;

+    }

+    

+    /**

+     * Get the error message.

+     * @return the error message.

+     * @see java.lang.Throwable#getMessage()

+     */

+    public String getMessage() {

+        return "The configuration is not correct for the type " + m_type + " : " + m_message;

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/DefaultServiceContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/DefaultServiceContext.java
deleted file mode 100644
index 6c8fa72..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/DefaultServiceContext.java
+++ /dev/null
@@ -1,160 +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;
-
-import java.util.Dictionary;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Default iPOJO Service Context. this service context delegate all calls on the
- * bundle context.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class DefaultServiceContext implements ServiceContext {
-
-    /**
-     * The bundle context on which delegate.
-     */
-    private BundleContext m_context;
-
-    /**
-     * Constructor.
-     * 
-     * @param bc : the bundle context on which delegate.
-     */
-    public DefaultServiceContext(BundleContext bc) {
-        m_context = bc;
-    }
-
-    /**
-     * Add a service listener.
-     * @param listener : the service listener to add.
-     * @param filter : the LDAP filter
-     * @throws InvalidSyntaxException : occurs when the LDAP filter is malformed
-     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener, java.lang.String)
-     */
-    public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
-        m_context.addServiceListener(listener, filter);
-    }
-
-    /**
-     * Add a service listener.
-     * @param listener : the service listener to add.
-     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)
-     */
-    public void addServiceListener(ServiceListener listener) {
-        m_context.addServiceListener(listener);
-    }
-
-    /**
-     * Get the service references matching with the given query.
-     * @param clazz : Required interface
-     * @param filter : LDAP filter
-     * @return the array of available service reference
-     * @throws InvalidSyntaxException : occurs if the LDAP filter is malformed
-     * @see org.apache.felix.ipojo.ServiceContext#getAllServiceReferences(java.lang.String, java.lang.String)
-     */
-    public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        return m_context.getAllServiceReferences(clazz, filter);
-    }
-
-    /**
-     * Get a service object.
-     * @param reference : the required service reference 
-     * @return the service object or null if the service reference is no more valid or if the service object is not accessible
-     * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
-     */
-    public Object getService(ServiceReference reference) {
-        return m_context.getService(reference);
-    }
-
-    /**
-     * Get a service reference for the given interface.
-     * @param clazz : the required interface name
-     * @return a service reference on a available provider or null if no provider available
-     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
-     */
-    public ServiceReference getServiceReference(String clazz) {
-        return m_context.getServiceReference(clazz);
-    }
-
-    /**
-     * Get service reference list for the given query.
-     * @param clazz : the name of the required service interface
-     * @param filter : LDAP filter to apply on service provider
-     * @return : the array of consistent service reference or null if no available provider
-     * @throws InvalidSyntaxException : occurs if the LDAP filter is malformed
-     * @see org.apache.felix.ipojo.ServiceContext#getServiceReferences(java.lang.String, java.lang.String)
-     */
-    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        return m_context.getServiceReferences(clazz, filter);
-    }
-
-    /**
-     * Register a service.
-     * @param clazzes : interfaces provided by the service.
-     * @param service : the service object.
-     * @param properties : service properties.
-     * @return the service registration for this service publication.
-     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
-     */
-    public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties) {
-        return m_context.registerService(clazzes, service, properties);
-    }
-
-    /**
-     * Register a service.
-     * @param clazz : interface provided by the service.
-     * @param service : the service object.
-     * @param properties : service properties.
-     * @return the service registration for this service publication.
-     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
-     */
-    public ServiceRegistration registerService(String clazz, Object service, Dictionary properties) {
-        return m_context.registerService(clazz, service, properties);
-    }
-
-
-    /**
-     * Remove a service listener.
-     * @param listener : the service listener to remove
-     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
-     */
-    public void removeServiceListener(ServiceListener listener) {
-        m_context.removeServiceListener(listener);
-
-    }
-
-    /**
-     * Unget the service reference.
-     * @param reference : the service reference to unget
-     * @return true if you are the last user of the reference
-     * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
-     */
-    public boolean ungetService(ServiceReference reference) {
-        return m_context.ungetService(reference);
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
index dd8fabd..6c756e3 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
@@ -66,7 +66,6 @@
      */

     private long m_bundleId;

     

-    

     /**

      * Bundle Listener Notification.

      * @param event : the bundle event.

@@ -160,10 +159,15 @@
         m_components = new Hashtable();

         m_creators = new Hashtable();

         

-        synchronized (this) {

-            for (int i = 0; i < bc.getBundles().length; i++) {

-                if (bc.getBundles()[i].getState() == Bundle.ACTIVE) {

-                    startManagementFor(bc.getBundles()[i]);

+        // Begin by initializing core handlers

+        startManagementFor(bc.getBundle());

+        

+        synchronized (m_components) {

+            synchronized (m_creators) {

+                for (int i = 0; i < bc.getBundles().length; i++) {

+                    if (bc.getBundles()[i].getState() == Bundle.ACTIVE) {

+                        startManagementFor(bc.getBundles()[i]);

+                    }

                 }

             }

         }

@@ -190,7 +194,7 @@
         m_components = null;

         Enumeration e2 = m_creators.keys();

         while (e2.hasMoreElements()) {

-            InstanceCreator creator = (InstanceCreator) m_creators.get(e2.nextElement());

+            InstanceCreator creator = (InstanceCreator) m_creators.remove(e2.nextElement());

             creator.stop();

         }

         m_creators = null;

@@ -201,9 +205,18 @@
      * @param cm : the new component metadata.

      * @param bundle : the bundle.

      */

-    private void addComponentFactory(Bundle bundle, Element cm) {        

-        ComponentFactory factory = new ComponentFactory(bundle.getBundleContext(), cm);

-        

+    private void addComponentFactory(Bundle bundle, Element cm) {

+        ComponentFactory factory = null;

+        if (cm.getName().equalsIgnoreCase("component")) {

+            factory = new ComponentFactory(bundle.getBundleContext(), cm);

+        } else if (cm.getName().equalsIgnoreCase("composite")) {

+            factory = new CompositeFactory(bundle.getBundleContext(), cm);

+        } else if (cm.getName().equalsIgnoreCase("handler")) {

+            factory = new HandlerFactory(bundle.getBundleContext(), cm);

+        } else {

+            err("Not recognized element type : " + cm.getName(), null);

+        }

+

         ComponentFactory[] cfs = (ComponentFactory[]) m_components.get(bundle);

         

         // If the factory array is not empty add the new factory at the end

@@ -219,7 +232,7 @@
     }

     

     /**

-     * Start the management factories and create instances.

+     * Start the management of factories and create instances.

      * @param bundle : the bundle. 

      * @param confs : the instances to create.

      */

@@ -227,43 +240,15 @@
         ComponentFactory[] cfs = (ComponentFactory[]) m_components.get(bundle);

         

         // Start the factories

-        for (int j = 0; cfs != null && j < cfs.length; j++) {

-            cfs[j].start();

-        }

-

-        Dictionary[] outsiders = new Dictionary[0];

-        

-        for (int i = 0; confs != null && i < confs.length; i++) {

-            Dictionary conf = confs[i];

-            boolean created = false;

-            for (int j = 0; cfs != null && j < cfs.length; j++) {

-                String componentClass = cfs[j].getComponentClassName();

-                String factoryName = cfs[j].getName();

-                String componentName = cfs[j].getComponentTypeName();

-                if (conf.get("component") != null && (conf.get("component").equals(componentClass) || conf.get("component").equals(factoryName)) || conf.get("component").equals(componentName)) {

-                    try {

-                        cfs[j].createComponentInstance(conf);

-                        created = true;

-                    } catch (UnacceptableConfiguration e) {

-                        System.err.println("Cannot create the instance " + conf.get("name") + " : " + e.getMessage());

-                    }

-                }

-            }

-            if (!created && conf.get("component") != null) {

-                if (outsiders.length != 0) {

-                    Dictionary[] newList = new Dictionary[outsiders.length + 1];

-                    System.arraycopy(outsiders, 0, newList, 0, outsiders.length);

-                    newList[outsiders.length] = conf;

-                    outsiders = newList;

-                } else {

-                    outsiders = new Dictionary[] { conf };

-                }

+        if (cfs != null) {

+            for (int j = 0; j < cfs.length; j++) {

+                cfs[j].start();

             }

         }

 

         // Create the instance creator if needed.

-        if (outsiders.length > 0) {

-            m_creators.put(bundle, new InstanceCreator(bundle.getBundleContext(), outsiders));

+        if (confs.length > 0) {

+            m_creators.put(bundle, new InstanceCreator(bundle.getBundleContext(), confs, cfs));

         }

     }

     

@@ -285,5 +270,4 @@
             System.err.println("[iPOJO-Core] " + message);

         }

     }

-

 }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java
index 7342e4c..9d309bf 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java
@@ -19,49 +19,62 @@
 package org.apache.felix.ipojo;
 
 import java.util.Dictionary;
+import java.util.List;
 
+import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.metadata.Element;
 
 /**
- * Component Type Factory Service. This service is exposed by a instance manager
- * factory, and allows the dynamic creation of component instance.
- * 
+ * Component Type Factory Service. This service is exposed by a instance manager factory, and allows the dynamic creation of component instance.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public interface Factory {
 
     /**
+     * Factory State. A valid factory is a factory where all required handlers are available.
+     */
+    int VALID = 1;
+
+    /**
+     * Factory State. An invalid factory is a factory where at least one required handler is unavailable. Creating an instance with an invalid factory failed.
+     */
+    int INVALID = 0;
+
+    /**
      * Create an instance manager (i.e. component type instance).
-     * 
      * @param configuration : the configuration properties for this component.
      * @return the created instance manager.
      * @throws UnacceptableConfiguration : when a given configuration is not valid.
+     * @throws MissingHandlerException : when an handler is missing.
+     * @throws ConfigurationException : when the instance configuration failed.
      */
-    ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration;
+    ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException;
 
     /**
-     * Create an instance manager (i.e. component type instance). This has these
-     * service interaction in the scope given in argument.
-     * 
+     * Create an instance manager (i.e. component type instance). This has these service interaction in the scope given in argument.
      * @param configuration : the configuration properties for this component.
      * @param serviceContext : the service context of the component.
      * @return the created instance manager.
      * @throws UnacceptableConfiguration : when the given configuration is not valid.
+     * @throws MissingHandlerException : when an handler is missing.
+     * @throws ConfigurationException : when the instance configuration failed.
      */
-    ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration;
+    ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException;
 
     /**
-     * Get the component type information containing provided service,
-     * configuration properties ...
-     * 
+     * Get the component type information containing provided service, configuration properties ...
      * @return the component type information.
      */
     Element getDescription();
 
     /**
-     * Check if the given configuration is acceptable as a configuration of a
-     * component instance.
-     * 
+     * Get the component type description.
+     * @return the component type description object
+     */
+    ComponentDescription getComponentDescription();
+
+    /**
+     * Check if the given configuration is acceptable as a configuration of a component instance.
      * @param conf : the configuration to test
      * @return true if the configuration is acceptable
      */
@@ -74,13 +87,35 @@
     String getName();
 
     /**
-     * Reconfigure an instance already created. This configuration need to have
-     * the name property to identify the instance.
-     * 
+     * Reconfigure an instance already created. This configuration need to have the name property to identify the instance.
      * @param conf : the configuration to reconfigure the instance.
-     * @throws UnacceptableConfiguration : if the given configuration is not
-     * consistent for the targeted instance.
+     * @throws UnacceptableConfiguration : if the given configuration is not consistent for the targeted instance.
+     * @throws MissingHandlerException : when an handler is missing.
      */
-    void reconfigure(Dictionary conf) throws UnacceptableConfiguration;
+    void reconfigure(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException;
+
+    /**
+     * Add a factory state listener on the current factory.
+     * @param l : the listener to add
+     */
+    void addFactoryStateListener(FactoryStateListener l);
+
+    /**
+     * Remove the given factory state listener from the listener list.
+     * @param l : the listener to remove
+     */
+    void removeFactoryStateListener(FactoryStateListener l);
+
+    /**
+     * Get the list of missing handlers.
+     * @return the list containing the name of missing handlers (Name : namespace:name)
+     */
+    List getMissingHandlers();
+
+    /**
+     * Get the list of required handlers.
+     * @return the list containing the name of required handlers (Name : namespace:name)
+     */
+    List getRequiredHandlers();
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java
new file mode 100644
index 0000000..1d3fb59
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java
@@ -0,0 +1,35 @@
+/* 

+ * 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;

+

+/**

+ * Factory state listener.

+ * This listener allows anyone to be notified when the listened factory state changes. 

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public interface FactoryStateListener {

+    

+    /**

+     * State change listener.

+     * Each time an instance state change, this method is called.

+     * @param factory : changing factory

+     * @param newState : new instance state

+     */

+    void stateChanged(Factory factory, int newState);

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java
index b9618e4..762bd3a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java
@@ -20,25 +20,110 @@
 
 import java.util.Dictionary;
 
+import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
 
 /**
- * Handler Abstract Class. An handler need implements these method to be notified
- * of lifecycle change, GETFIELD & PUTFIELD instruction as well as method entry and exit.
+ * Handler Abstract Class.
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public abstract class Handler {
+    
+    /**
+     * Handler namespace property.
+     */
+    public static final String HANDLER_NAMESPACE_PROPERTY = "handler.namespace";
+    
+    /**
+     * Handler name property. 
+     */
+    public static final String HANDLER_NAME_PROPERTY = "handler.name";
+    
+    /**
+     * Handler type property. 
+     */
+    public static final String HANDLER_TYPE_PROPERTY = "handler.type";
+    
+    /**
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
+     */
+    public abstract void log(int level, String message);
+    
+    /**
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
+     * @param ex : exception to attach to the message
+     */
+    public abstract void log(int level, String message, Throwable ex);
+    
+    /**
+     * Get a plugged handler of the same container.
+     * This method must be call only in the start method (or after). 
+     * In the configure method, this method can not return a consistent
+     * result as all handlers are not plugged. 
+     * @param name : name of the handler to find (class name or qualified handler name (ns:name)). 
+     * @return the handler object or null if the handler is not found.
+     */
+    public abstract Handler getHandler(String name);
+    
+    /**
+     * Attach the current handler object to the given component instance.
+     * An attached handler becomes a part of the instance container.
+     * @param ci : the component instance on which the current handler will be attached.
+     */
+    protected abstract void attach(ComponentInstance ci);
+    
+    /**
+     * Check if the current handler is valid.
+     * This method must not be override.
+     * @return true if the handler is valid.
+     */
+    public final boolean isValid() {
+        if (this instanceof Pojo) {
+            return getInstance().getState() == ComponentInstance.VALID;
+        } else {
+            log(Logger.ERROR, "The handler is not a POJO : " + this.getClass().getName());
+            return false;
+        }
+    }
+    
+    
+    /**
+     * Get the component instance of the current handler.
+     * @return : the component instance.
+     */
+    public final ComponentInstance getInstance() {
+        if (this instanceof Pojo) {
+            return ((Pojo) this).getComponentInstance();
+        } else {
+            log(Logger.ERROR, "The handler is not a POJO : " + this.getClass().getName());
+            return null;
+        }
+    }
+    
+    /**
+     * Initialize component factory.
+     * This method aims to gather component factory properties. Each handler wanting to contribute need to override this 
+     * method and add properties to the given component description.
+     * @param cd : component description.
+     * @param metadata : component type metadata.
+     * @throws ConfigurationException : if the metadata are not correct (early detection).
+     */
+    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {  }
 
     /**
      * Configure the handler.
-     * 
-     * @param im : the instance manager
      * @param metadata : the metadata of the component
      * @param configuration : the instance configuration
+     * @throws ConfigurationException : if the metadata are not correct.
      */
-    public abstract void configure(InstanceManager im, Element metadata, Dictionary configuration);
+    public abstract void configure(Element metadata, Dictionary configuration) throws ConfigurationException;
 
     /**
      * Stop the handler : stop the management.
@@ -51,69 +136,10 @@
     public abstract void start();
 
     /**
-     * This method is called when a PUTFIELD operation is detected.
-     * 
-     * @param fieldName : the field name
-     * @param value : the value passed to the field
-     */
-    public void setterCallback(String fieldName, Object value) {
-    }
-
-    /**
-     * This method is called when a GETFIELD operation is detected.
-     * 
-     * @param fieldName : the field name
-     * @param value : the value passed to the field (by the previous handler)
-     * @return : the managed value of the field
-     */
-    public Object getterCallback(String fieldName, Object value) {
-        return value;
-    }
-    
-    /**
-     * This method is called when the execution enter in a method.
-     * 
-     * @param methodId : the method identifier
-     */
-    public void entryCallback(String methodId) {
-    }
-
-    /**
-     * This method is called when the execution exit a method (before a return or a throw).
-     * If the given returned object is an instance of Exception, this means that the method throwed this exception.
-     * If the given returned object is null, either the method is void, either it returns null.
-     * You must not modified the returned object.
-     * @param methodId : the method identifier
-     * @param returnedObj : the returned object (boxed for primitive type)
-     */
-    public void exitCallback(String methodId, Object returnedObj) {
-    }
-
-    /**
-     * Is the actual state valid for this handler ?
-     * 
-     * @return true is the state seems valid for the handler
-     */
-    public boolean isValid() {
-        return true;
-    }
-
-    /**
      * This method is called when the component state changed.
-     * 
      * @param state : the new state
      */
-    public void stateChanged(int state) {
-    }
-
-    /**
-     * This method is called when an instance of the component is created, but
-     * before someone can use it.
-     * 
-     * @param instance : the created instance
-     */
-    public void createInstance(Object instance) {
-    }
+    public void stateChanged(int state) { }
 
     /**
      * Return the current handler description.
@@ -121,14 +147,12 @@
      * @return the description of the handler..
      */
     public HandlerDescription getDescription() {
-        return new HandlerDescription(this.getClass().getName(), isValid());
+        return new HandlerDescription(this);
     }
 
     /**
      * The instance is reconfiguring.
-     * 
      * @param configuration : New instance configuration.
      */
-    public void reconfigure(Dictionary configuration) {
-    }
+    public void reconfigure(Dictionary configuration) { }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
new file mode 100644
index 0000000..80f8aa0
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
@@ -0,0 +1,258 @@
+/* 

+ * 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;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.util.Logger;

+import org.apache.felix.ipojo.util.Tracker;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Constants;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * The component factory manages component instance objects. This management

+ * consist in creating and managing component instance build with the component

+ * factory. This class could export Factory and ManagedServiceFactory services.

+ * 

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class HandlerFactory extends ComponentFactory implements Factory {

+

+    /**

+     * Service Registration of this factory (Factory & ManagedServiceFactory).

+     */

+    private ServiceRegistration m_sr;

+    

+    /**

+     * Handler type (composite|primitive).

+     * Default: handler.

+     */

+    private String m_type = "primitive";

+    

+    /**

+     * Default iPOJO Namespace.

+     */

+    private String m_namespace = IPojoConfiguration.IPOJO_NAMESPACE;

+

+    /**

+     * Create a composite factory.

+     * @param bc : bundle context

+     * @param cm : metadata of the component to create

+     */

+    public HandlerFactory(BundleContext bc, Element cm) {

+        super(bc, cm);

+        

+        // Get the name

+        if (cm.containsAttribute("name")) {

+            m_typeName = cm.getAttribute("name").toLowerCase();

+        } else {

+            System.err.println("An Handler needs a name");

+            return;

+        }

+        

+        // Get the type

+        if (cm.containsAttribute("type")) {

+            m_type = cm.getAttribute("type");

+        }

+        

+        // Get the namespace

+        if (cm.containsAttribute("namespace")) {

+            m_namespace = cm.getAttribute("namespace").toLowerCase();

+        }        

+    }

+    

+    public String getNamespace() {

+        return m_namespace;

+    }

+    

+    public String getHandlerName() {

+        return m_namespace + ":" + getName();

+    }

+    

+    public String getType() {

+        return m_type;

+    }

+

+    /**

+     * Start all the instance managers.

+     */

+    public synchronized void start() {

+        if (m_componentDesc != null) { // Already started.

+            return;

+        } 

+        

+        try {

+            String filter = "(&(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")"

+                    + "(" + Handler.HANDLER_NAME_PROPERTY + "=*)" + "(" + Handler.HANDLER_NAMESPACE_PROPERTY + "=*)" /* Look only for handlers */

+                    + "(" + Handler.HANDLER_TYPE_PROPERTY + "=" + PrimitiveHandler.HANDLER_TYPE + ")" 

+                    + "(factory.state=1)"

+                    + ")";

+            m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);

+            m_tracker.open();

+            

+        } catch (InvalidSyntaxException e) {

+            m_logger.log(Logger.ERROR, "A factory filter is not valid: " + e.getMessage());

+            return;

+        }

+                

+        computeFactoryState();

+        

+        // Check if the factory should be exposed

+        if (m_factoryName == null) { return; }

+        

+        // Exposition of the factory service

+        m_sr = m_context.registerService(new String[] { Factory.class.getName()}, this, getProperties());

+    }

+    

+    /**

+     * Stop the factory.

+     * This method does not disposed created instances.

+     * These instances will be disposed by the instance managers.

+     */

+    public synchronized void stop() {

+        if (m_sr != null) {

+            m_sr.unregister();

+            m_sr = null;

+        }

+        

+        m_tracker.close();

+        

+        // Release each handler

+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {

+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);

+            if (hi.getReference() != null) {

+                hi.setReference(null);

+            }

+        }

+        

+        m_handlerIdentifiers.clear();        

+        m_listeners.clear();

+        m_tracker = null;

+        m_componentDesc = null;

+        m_state = INVALID;        

+    }

+    

+    

+    /**

+     * Compute factory service properties.

+     * This method add three mandatory handler factory properties (name, namespace and type)

+     * @return the properties.

+     * @see org.apache.felix.ipojo.ComponentFactory#getProperties()

+     */

+    protected Properties getProperties() {

+        final Properties props = super.getProperties();

+

+        props.put(Handler.HANDLER_NAME_PROPERTY, m_typeName);

+        props.put(Handler.HANDLER_NAMESPACE_PROPERTY, m_namespace);

+        props.put(Handler.HANDLER_TYPE_PROPERTY, m_type);

+        

+        return props;

+    }

+    

+    /**

+     * Create an instance. The given configuration needs to contain the 'name'

+     * property.

+     * @param configuration : configuration of the created instance.

+     * @param serviceContext : the service context to push for this instance.

+     * @return the created component instance.

+     * @throws UnacceptableConfiguration : occurs if the given configuration is

+     * not consistent with the component type of this factory.

+     * @throws MissingHandlerException : occurs when an handler is unavailable when creating the instance.

+     * @throws org.apache.felix.ipojo.ConfigurationException : when the instance configuration failed.

+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)

+     */

+    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {

+        if (m_state == INVALID) {

+            throw new MissingHandlerException(getMissingHandlers());

+        }

+        

+        if (configuration == null) {

+            configuration = new Properties();

+        }

+        

+        try {

+            checkAcceptability(configuration);

+        } catch (UnacceptableConfiguration e) {

+            m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());

+            throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage());

+        }

+

+        

+        String in = null;

+        if (configuration.get("name") != null) {

+            in = (String) configuration.get("name");

+        } else {

+            in = generateName();

+            configuration.put("name", in);

+        }

+        

+        if (m_instancesName.contains(in)) {

+            throw new UnacceptableConfiguration("Name already used : " + in);

+        } else {

+            m_instancesName.add(in);

+        }

+

+        BundleContext context = null;

+        if (serviceContext == null) {

+            context = new IPojoContext(m_context);

+        } else {

+            context = new IPojoContext(m_context, serviceContext);

+        }

+        List handlers = new ArrayList();

+        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {

+            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);

+            handlers.add(getHandlerInstance(hi, serviceContext));

+        }

+        HandlerManager instance = new HandlerManager(this, context, (HandlerManager[]) handlers.toArray(new HandlerManager[0]));

+        instance.configure(m_componentMetadata, configuration);

+

+        m_componentInstances.put(in, instance);

+        

+        

+        return instance;

+    }

+    

+    /**

+     * Return an handler object.

+     * @param hi : handler to create.

+     * @param sc : service context in which create the handler (instance context).

+     * @return the Handler object.

+     */

+    private HandlerManager getHandlerInstance(HandlerIdentifier hi, ServiceContext sc) {

+        Factory factory = hi.getFactory();

+        try {

+            return (HandlerManager) factory.createComponentInstance(null, sc);

+        } catch (MissingHandlerException e) {

+            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed: " + e.getMessage());

+            return null;

+        } catch (UnacceptableConfiguration e) {

+            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());

+            return null;

+        } catch (org.apache.felix.ipojo.ConfigurationException e) {

+            m_logger.log(Logger.ERROR, "The configuration of the handler " + hi.getFullName() + " has failed (ConfigurationException): " + e.getMessage());

+            return null;

+        }

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
new file mode 100644
index 0000000..0d5fa79
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
@@ -0,0 +1,159 @@
+/* 

+ * 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;

+

+import java.util.Dictionary;

+

+import org.apache.felix.ipojo.metadata.Element;

+import org.osgi.framework.BundleContext;

+

+/**

+* The handler manager manages an handler instance.

+* 

+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+*/

+public class HandlerManager extends InstanceManager {

+    

+    /**

+     * Handler object (contained).

+     */

+    private Handler m_handler;

+

+    /**

+     * Constructor.

+     * @param factory : handler factory

+     * @param bc : bundle context

+     * @param handlers : handler array

+     */

+    public HandlerManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {

+        super(factory, bc, handlers);

+    }

+    

+    /**

+     * Get the contained handler object.

+     * If not already created it creates the object.

+     * @return the handler object.

+     */

+    public Handler getHandler() {

+        if (m_handler == null) {

+            createHandlerObject();

+        }

+        return m_handler;

+    }

+    

+    /**

+     * Create and initialize the handler object.

+     * @param ci : component instance on which the handler will be attached.

+     * @param cm : component metadata.

+     * @param configuration : instance configuration.

+     * @throws ConfigurationException if the handler configuration failed.

+     */

+    public void init(ComponentInstance ci, Element cm, Dictionary configuration) throws ConfigurationException {

+        createHandlerObject();

+        m_handler.attach(ci);

+        m_handler.configure(cm, configuration);

+    }

+    

+    /**

+     * Create the handler object.

+     * This method does nothing if the object is already created.

+     */

+    private void createHandlerObject() {

+        if (m_handler != null) { return; }

+        Handler h  = (Handler) createPojoObject();

+        if (h instanceof PrimitiveHandler) {

+            m_handler = (PrimitiveHandler) h;

+        } else {

+            m_handler = (CompositeHandler) h;

+        }

+    }

+    

+    /**

+     * Start the instance manager.

+     */

+    public synchronized void start() {

+        if (m_state != STOPPED) {

+            return;

+        } // Instance already started

+

+        for (int i = 0; i < m_handlers.length; i++) {

+            m_handlers[i].addInstanceStateListener(this);

+            m_handlers[i].start();

+        }

+        

+        m_handler.start(); // Call the handler start method.

+        

+        for (int i = 0; i < m_handlers.length; i++) {

+            if (! m_handlers[i].getHandler().isValid()) {

+                setState(INVALID);

+                return;

+            }

+        }

+        setState(VALID);

+    }

+    

+    /**

+     * Stop the instance manager.

+     */

+    public synchronized void stop() {

+        if (m_state == STOPPED) {

+            return;

+        } // Instance already stopped

+        

+

+        setState(INVALID);

+        

+        m_handler.stop();

+        

+        // Stop all the handlers

+        for (int i = m_handlers.length - 1; i > -1; i--) {

+            m_handlers[i].removeInstanceStateListener(this);

+            m_handlers[i].stop();

+        }

+

+        m_state = STOPPED;

+        for (int i = 0; i < m_instanceListeners.size(); i++) {

+            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);

+        }

+    }

+    

+    /** 

+     * Dispose the instance.

+     * @see org.apache.felix.ipojo.ComponentInstance#dispose()

+     */

+    public synchronized void dispose() {

+        super.dispose();

+        m_handler = null;

+    }

+    

+    /**

+     * Kill the current instance.

+     * Only the factory of this instance can call this method.

+     */

+    protected void kill() {

+        super.dispose();

+        m_handler = null;

+    }

+

+    

+    

+    

+   

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
index f82b53e..78d3434 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
@@ -19,7 +19,7 @@
 package org.apache.felix.ipojo;
 
 import org.apache.felix.ipojo.composite.instance.InstanceHandler;
-import org.apache.felix.ipojo.composite.service.importer.ImportExportHandler;
+import org.apache.felix.ipojo.composite.service.importer.ImportHandler;
 import org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler;
 import org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler;
 import org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler;
@@ -39,6 +39,12 @@
      * iPOJO logger log level.
      */
     public static final int LOG_LEVEL = Logger.WARNING;
+    
+    
+    /**
+     * iPOJO Default Namespace.
+     */
+    public static final String IPOJO_NAMESPACE = "org.apache.felix.ipojo";
 
     /**
      * Available handlers in the iPOJO bundle.
@@ -57,10 +63,11 @@
      */
     public static final Class[] INTERNAL_COMPOSITE_HANDLERS = new Class[] { 
         ServiceInstantiatorHandler.class, 
-        ImportExportHandler.class,
+        ImportHandler.class,
         InstanceHandler.class,
         org.apache.felix.ipojo.composite.service.provides.ProvidedServiceHandler.class,
         org.apache.felix.ipojo.composite.architecture.ArchitectureHandler.class
     };
+    
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
index de1c44a..a1e2e53 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
@@ -39,7 +39,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class IPojoContext implements BundleContext {
+public class IPojoContext implements BundleContext, ServiceContext {
 
     /**
      * BundleContext used to access bundle method.
@@ -58,7 +58,6 @@
      */
     public IPojoContext(BundleContext bc) {
         m_bundleContext = bc;
-        m_serviceContext = new DefaultServiceContext(bc);
     }
 
     /**
@@ -100,7 +99,11 @@
      * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener, java.lang.String)
      */
     public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
-        m_serviceContext.addServiceListener(listener, filter);
+        if (m_serviceContext == null) {
+            m_bundleContext.addServiceListener(listener, filter);
+        } else {
+            m_serviceContext.addServiceListener(listener, filter);
+        }
     }
 
     /**
@@ -109,7 +112,11 @@
      * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener)
      */
     public void addServiceListener(ServiceListener listener) {
-        m_serviceContext.addServiceListener(listener);
+        if (m_serviceContext == null) {
+            m_bundleContext.addServiceListener(listener);
+        } else {
+            m_serviceContext.addServiceListener(listener);
+        }
     }
 
 
@@ -133,7 +140,11 @@
      * @see org.osgi.framework.BundleContext#getAllServiceReferences(java.lang.String, java.lang.String)
      */
     public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        return m_serviceContext.getAllServiceReferences(clazz, filter);
+        if (m_serviceContext == null) {
+            return m_bundleContext.getAllServiceReferences(clazz, filter);
+        } else {
+            return m_serviceContext.getAllServiceReferences(clazz, filter);
+        }
     }
 
     /**
@@ -192,7 +203,11 @@
      * @see org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
      */
     public Object getService(ServiceReference reference) {
-        return m_serviceContext.getService(reference);
+        if (m_serviceContext == null) {
+            return m_bundleContext.getService(reference);
+        } else {
+            return m_serviceContext.getService(reference);
+        }
     }
 
     /**
@@ -202,7 +217,11 @@
      * @see org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
      */
     public ServiceReference getServiceReference(String clazz) {
-        return m_serviceContext.getServiceReference(clazz);
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReference(clazz);
+        } else {
+            return m_serviceContext.getServiceReference(clazz);
+        }
     }
 
     /**
@@ -214,7 +233,11 @@
      * @see org.osgi.framework.BundleContext#getServiceReferences(java.lang.String, java.lang.String)
      */
     public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        return m_serviceContext.getServiceReferences(clazz, filter);
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReferences(clazz, filter);
+        } else {
+            return m_serviceContext.getServiceReferences(clazz, filter);
+        }
     }
 
     /**
@@ -249,7 +272,11 @@
      * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
      */
     public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties) {
-        return m_serviceContext.registerService(clazzes, service, properties);
+        if (m_serviceContext == null) {
+            return m_bundleContext.registerService(clazzes, service, properties);
+        } else {
+            return m_serviceContext.registerService(clazzes, service, properties);
+        }
     }
 
     /**
@@ -261,7 +288,11 @@
      * @see org.osgi.framework.BundleContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
      */
     public ServiceRegistration registerService(String clazz, Object service, Dictionary properties) {
-        return m_serviceContext.registerService(clazz, service, properties);
+        if (m_serviceContext == null) {
+            return m_bundleContext.registerService(clazz, service, properties);
+        } else {
+            return m_serviceContext.registerService(clazz, service, properties);
+        }
     }
 
     /**
@@ -289,7 +320,11 @@
      * @see org.osgi.framework.BundleContext#removeServiceListener(org.osgi.framework.ServiceListener)
      */
     public void removeServiceListener(ServiceListener listener) {
-        m_serviceContext.removeServiceListener(listener);
+        if (m_serviceContext == null) {
+            m_bundleContext.removeServiceListener(listener);
+        } else {
+            m_serviceContext.removeServiceListener(listener);
+        }
     }
 
     /**
@@ -299,7 +334,11 @@
      * @see org.osgi.framework.BundleContext#ungetService(org.osgi.framework.ServiceReference)
      */
     public boolean ungetService(ServiceReference reference) {
-        return m_serviceContext.ungetService(reference);
+        if (m_serviceContext == null) {
+            return m_bundleContext.ungetService(reference);
+        } else {
+            return m_serviceContext.ungetService(reference);
+        }
     }
     
     /**
@@ -315,6 +354,9 @@
      * @return the service context.
      */
     public ServiceContext getServiceContext() {
+        if (m_serviceContext == null) {
+            return this;
+        }
         return m_serviceContext;
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
index b502477..5f8edcc 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
@@ -21,10 +21,10 @@
 import java.util.Dictionary;
 
 import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -33,7 +33,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceCreator implements ServiceListener {
+public class InstanceCreator implements TrackerCustomizer, FactoryStateListener {
     /**
      * Bundle Context.
      */
@@ -43,6 +43,11 @@
      * Logger to log messages if error occurs.
      */
     private Logger m_logger;
+    
+    /**
+     * Private factories.
+     */
+    private ComponentFactory[] m_factories;
 
     /**
      * This structure aims to manage a configuration. It stores all necessary
@@ -122,44 +127,52 @@
     private ManagedConfiguration[] m_configurations = new ManagedConfiguration[0];
 
     /**
+     * Service Tracker tracking factories.
+     */
+    private Tracker m_tracker;
+
+    /**
      * Constructor.
      * 
      * @param context : the bundle context.
      * @param configurations : configuration set to create and maintain.
+     * @param factories : private factories.
      */
-    public InstanceCreator(BundleContext context, Dictionary[] configurations) {
+    public InstanceCreator(BundleContext context, Dictionary[] configurations, ComponentFactory[] factories) {
         m_context = context;
         m_logger = new Logger(context, "InstanceCreator" + context.getBundle().getBundleId(), Logger.WARNING);
+        
         m_configurations = new ManagedConfiguration[configurations.length];
+        m_factories = factories;
+       
         for (int i = 0; i < configurations.length; i++) {
             ManagedConfiguration conf = new ManagedConfiguration(configurations[i]);
             m_configurations[i] = conf;
-
             // Get the component type name :
             String componentType = (String) conf.getConfiguration().get("component");
-            Factory fact = null;
 
-            try {
-                String fil = "(|(" + org.osgi.framework.Constants.SERVICE_PID + "=" + componentType + ")" 
-                    + "(component.class=" + componentType + ")(component.type=" + componentType + "))";
-                ServiceReference[] refs = context.getServiceReferences(org.apache.felix.ipojo.Factory.class.getName(), fil);
-                if (refs != null) {
-                    fact = (Factory) m_context.getService(refs[0]);
-                    createInstance(fact, conf);
-                } else {
-                    m_logger.log(Logger.WARNING, "No factory available for the type : " + componentType);
+            boolean found = false;
+            for (int j = 0; m_factories != null && !found && j < m_factories.length; j++) {
+                if (m_factories[j].m_state == Factory.VALID && (m_factories[j].getName().equals(componentType) || (m_factories[j].getComponentClassName() != null && m_factories[j].getComponentClassName().equals(componentType)))) {
+                    createInstance(m_factories[j], conf);
+                    found = true;
                 }
-            } catch (InvalidSyntaxException e) {
-                m_logger.log(Logger.ERROR, "Invalid syntax filter for the type : " + componentType, e);
             }
         }
-
-        // Register a service listener on Factory Service
-        try {
-            m_context.addServiceListener(this, "(objectClass=" + Factory.class.getName() + ")");
-        } catch (InvalidSyntaxException e) {
-            m_logger.log(Logger.ERROR, "Invalid syntax filter when registering a listener on Factory Service", e);
+        
+        for (int i = 0; m_factories != null && i < m_factories.length; i++) {
+            m_factories[i].addFactoryStateListener(this);
         }
+       
+        
+        String filter = "(&(objectclass=" + Factory.class.getName() + ")(factory.state=1))";
+        try {
+            m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
+            m_tracker.open();
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+            return;
+        } 
     }
 
     /**
@@ -175,40 +188,10 @@
             config.setFactory(fact.getName());
         } catch (UnacceptableConfiguration e) {
             m_logger.log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
-        }
-    }
-
-    /**
-     * Service Listener implementation.
-     * @param ev : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent ev) {
-        ServiceReference ref = ev.getServiceReference();
-        String factoryName = (String) ref.getProperty(org.osgi.framework.Constants.SERVICE_PID);
-        String componentClass = (String) ref.getProperty("component.class");
-
-        if (ev.getType() == ServiceEvent.REGISTERED) { // A new factory appears
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() == null
-                        && (m_configurations[i].getConfiguration().get("component").equals(factoryName) || m_configurations[i].getConfiguration().get(
-                                "component").equals(componentClass))) {
-                    Factory fact = (Factory) m_context.getService(ref);
-                    createInstance(fact, m_configurations[i]);
-                }
-            }
-            return;
-        }
-
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factoryName)) {
-                    m_configurations[i].setInstance(null);
-                    m_configurations[i].setFactory(null);
-                    m_context.ungetService(ref);
-                }
-            }
-            return;
+        } catch (MissingHandlerException e) {
+            m_logger.log(Logger.ERROR, "The instance creation has failed, at least one handler is missing", e);
+        } catch (ConfigurationException e) {
+            m_logger.log(Logger.ERROR, "The instance creation has failed, an error during the configuration has occured", e);
         }
     }
 
@@ -216,7 +199,12 @@
      * Stop all created instances.
      */
     public synchronized void stop() {
-        m_context.removeServiceListener(this);
+        m_tracker.close();
+        
+        for (int i = 0; m_factories != null && i < m_factories.length; i++) {
+            m_factories[i].removeFactoryStateListener(this);
+        }
+        
         for (int i = 0; i < m_configurations.length; i++) {
             if (m_configurations[i].getInstance() != null) {
                 m_configurations[i].getInstance().dispose();
@@ -224,7 +212,93 @@
             m_configurations[i].setInstance(null);
             m_configurations[i].setFactory(null);
         }
+        
+        m_factories = null;
+        m_tracker = null;
+        m_logger = null;
         m_configurations = null;
     }
 
+    /**
+     * Factory state changed method.
+     * @param factory : factory.
+     * @param newState : new state.
+     * @see org.apache.felix.ipojo.FactoryStateListener#stateChanged(org.apache.felix.ipojo.Factory, int)
+     */
+    public void stateChanged(Factory factory, int newState) {
+        if (newState == Factory.VALID) {
+            for (int i = 0; i < m_configurations.length; i++) {
+                if (m_configurations[i].getInstance() == null
+                        && (m_configurations[i].getConfiguration().get("component").equals(factory.getName()) || m_configurations[i].getConfiguration().get(
+                                "component").equals(((ComponentFactory) factory).getComponentClassName()))) {
+                    Factory fact = factory;
+                    createInstance(fact, m_configurations[i]);
+                }
+            }
+            return;
+        } else {
+            // newState == INVALID
+            for (int i = 0; i < m_configurations.length; i++) {
+                if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factory.getName())) {
+                    m_configurations[i].setInstance(null);
+                    m_configurations[i].setFactory(null);
+                }
+            }
+            return;
+        }
+    }
+
+    /**
+     * A new factory has been detected.
+     * @param ref : the factory service reference.
+     * @return true if the factory can be used to create a managed instance.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference ref) {
+        String factoryName = (String) ref.getProperty("factory.name");
+        String componentClass = (String) ref.getProperty("component.class");
+        boolean isValid = ((String) ref.getProperty("factory.state")).equals("" + Factory.VALID); 
+        Factory fact = (Factory) m_tracker.getService(ref);
+
+        boolean used = false;
+        if (isValid) {
+            for (int i = 0; i < m_configurations.length; i++) {
+                if (m_configurations[i].getInstance() == null
+                        && (m_configurations[i].getConfiguration().get("component").equals(factoryName) || m_configurations[i].getConfiguration().get("component").equals(componentClass))) {
+                    createInstance(fact, m_configurations[i]);
+                    used = true;
+                }
+            }
+        }
+        return used;
+    }
+
+    /**
+     * A used factory is modified.
+     * @param ref : modified reference.
+     * @param obj : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference ref, Object obj) {
+        // Nothing to do.
+    }
+
+    /**
+     * A used factory disappears.
+     * All created instance are disposed.
+     * @param ref : service reference.
+     * @param obj : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference ref, Object obj) {
+        Factory fact = (Factory) obj;
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(fact.getName())) {
+                m_configurations[i].setInstance(null);
+                m_configurations[i].setFactory(null);
+            }
+        }
+        m_tracker.ungetService(ref);
+    }
+
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
index c7e2c30..982aacc 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -27,7 +27,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
@@ -41,34 +40,44 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceManager implements ComponentInstance {
+public class InstanceManager implements ComponentInstance, InstanceStateListener {
 
     /**
+     * Name of the component instance.
+     */
+    protected String m_name;
+
+    /**
+     * Name of the component type implementation class.
+     */
+    protected String m_className;
+    
+    /**
+     * Handler list.
+     */
+    protected HandlerManager[] m_handlers = new HandlerManager[0];
+
+    /**
+     * Component state (STOPPED at the beginning).
+     */
+    protected int m_state = STOPPED;
+    
+    /**
+     * Instance State Listener List.
+     */
+    protected List m_instanceListeners = new ArrayList();
+    
+    /**
      * Parent factory (ComponentFactory).
      */
     private ComponentFactory m_factory;
 
     /**
-     * Name of the component instance.
-     */
-    private String m_name;
-
-    /**
-     * Name of the component type implementation class.
-     */
-    private String m_className;
-
-    /**
      * The context of the component.
      */
     private BundleContext m_context;
 
     /**
-     * Handler list.
-     */
-    private Handler[] m_handlers = new Handler[0];
-
-    /**
      * Map [field, handler list] storing handlers interested by the field.
      */
     private Map m_fieldRegistration = new HashMap();
@@ -79,11 +88,6 @@
     private Map m_methodRegistration = new HashMap();
 
     /**
-     * Component state (STOPPED at the beginning).
-     */
-    private int m_state = STOPPED;
-
-    /**
      * Manipulated class.
      */
     private Class m_clazz;
@@ -92,17 +96,7 @@
      * Instances of the components.
      */
     private Object[] m_pojoObjects = new Object[0];
-    
-    /**
-     * Instance State Listener List.
-     */
-    private List m_instanceListeners = new ArrayList();
 
-    /**
-     * Component type information.
-     */
-    private ComponentDescription m_componentDesc;
-    
    /**
     * Is the component instance state changing?
     */
@@ -118,11 +112,12 @@
      * 
      * @param factory : the factory managing the instance manager
      * @param bc : the bundle context to give to the instance
+     * @param handlers : handlers array
      */
-    public InstanceManager(ComponentFactory factory, BundleContext bc) {
+    public InstanceManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
         m_factory = factory;
         m_context = bc;
-        m_factory.getLogger().log(Logger.INFO, "[Bundle " + m_context.getBundle().getBundleId() + "] Create an instance manager from the factory " + m_factory);
+        m_handlers = handlers;
     }
 
     /**
@@ -131,72 +126,18 @@
      * 
      * @param cm : the component type metadata
      * @param configuration : the configuration of the instance
+     * @throws ConfigurationException : occurs if the metadata are not correct
      */
-    public void configure(Element cm, Dictionary configuration) {
-        // Stop all previous registered handler
-        if (m_handlers.length != 0) {
-            stop();
-        }
-
-        // Clear the handler list
-        m_handlers = new Handler[0];
-
-        // Set the component-type metadata
+    public void configure(Element cm, Dictionary configuration) throws ConfigurationException {
         m_className = cm.getAttribute("className");
-        if (m_className == null) {
-            m_factory.getLogger().log(Logger.ERROR, "The class name of the component cannot be set, it does not exist in the metadata");
-        }
-
-        // ComponentInfo initialization
-        m_componentDesc = new ComponentDescription(m_factory.getName(), m_className, m_context.getBundle().getBundleId());
-
+        
         // Add the name
         m_name = (String) configuration.get("name");
         
         // Create the standard handlers and add these handlers to the list
-        for (int i = 0; i < IPojoConfiguration.INTERNAL_HANDLERS.length; i++) {
-            // Create a new instance
-            try {
-                Handler h = (Handler) IPojoConfiguration.INTERNAL_HANDLERS[i].newInstance();
-                h.configure(this, cm, configuration);
-            } catch (InstantiationException e) {
-                m_factory.getLogger().log(Logger.ERROR,
-                        "[" + m_name + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
-            } catch (IllegalAccessException e) {
-                m_factory.getLogger().log(Logger.ERROR,
-                        "[" + m_name + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
-            }
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].init(this, cm, configuration);
         }
-
-        // Look for namespaces
-        for (int i = 0; i < cm.getNamespaces().length; i++) {
-            if (!cm.getNamespaces()[i].equals("")) {
-                // It is not an internal handler, try to load it
-                try {
-                    Class c = m_context.getBundle().loadClass(cm.getNamespaces()[i]);
-                    Handler h = (Handler) c.newInstance();
-                    h.configure(this, cm, configuration);
-                } catch (ClassNotFoundException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                } catch (InstantiationException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                } catch (IllegalAccessException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                }
-            }
-        }
-    }
-
-    /**
-     * Get the component type description of the current instance.
-     * @return the component type information.
-     * @see org.apache.felix.ipojo.ComponentInstance#getComponentDescription()
-     */
-    public ComponentDescription getComponentDescription() {
-        return m_componentDesc;
     }
 
     /**
@@ -206,7 +147,7 @@
      */
     public InstanceDescription getInstanceDescription() {
         int componentState = getState();
-        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_componentDesc);
+        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
 
         String[] objects = new String[getPojoObjects().length];
         for (int i = 0; i < getPojoObjects().length; i++) {
@@ -226,59 +167,64 @@
      * @return the handler array of plugged handlers.
      */
     public Handler[] getRegistredHandlers() {
-        return m_handlers;
+        Handler[] h = new Handler[m_handlers.length];
+        for (int i = 0; i < m_handlers.length; i++) {
+            h[i] = m_handlers[i].getHandler();
+        }
+        return h;
     }
 
     /**
      * Return a specified handler.
      * 
-     * @param name : class name of the handler to find
+     * @param name : class name of the handler to find or its qualified name (namespace:name)
      * @return : the handler, or null if not found
      */
     public Handler getHandler(String name) {
         for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i].getClass().getName().equalsIgnoreCase(name)) {
-                return m_handlers[i];
+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getInstance().getFactory();
+            if (fact.getHandlerName().equals(name)) {
+                return m_handlers[i].getHandler();
             }
         }
         return null;
     }
 
-    // ===================== Lifecycle management =====================
-
     /**
      * Start the instance manager.
      */
-    public void start() {
+    public synchronized void start() {
         if (m_state != STOPPED) {
             return;
         } // Instance already started
-
-        // Start all the handlers
-        m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] Start the instance manager with " + m_handlers.length + " handlers");
-
-        // The new state of the component is UNRESOLVED
-        m_state = INVALID;
-
+        
         for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].addInstanceStateListener(this);
             m_handlers[i].start();
         }
-
-        // Defines the state of the component :
-        checkInstanceState();
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i].getState() != VALID) {
+                setState(INVALID);
+                return;
+            }
+        }
+        setState(VALID);
     }
 
     /**
      * Stop the instance manager.
      */
-    public void stop() {
+    public synchronized void stop() {
         if (m_state == STOPPED) {
             return;
         } // Instance already stopped
-
+        
         setState(INVALID);
+        
         // Stop all the handlers
         for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].removeInstanceStateListener(this);
             m_handlers[i].stop();
         }
         
@@ -294,22 +240,28 @@
      * Dispose the instance.
      * @see org.apache.felix.ipojo.ComponentInstance#dispose()
      */
-    public void dispose() {
+    public synchronized void dispose() {
         if (m_state > STOPPED) { // Valid or invalid
             stop();
         }
         
+        m_state = DISPOSED;
+        
         for (int i = 0; i < m_instanceListeners.size(); i++) {
             ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
         }
         
         m_factory.disposed(this);
-
-        // Cleaning
-        m_handlers = new Handler[0];
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].dispose();
+        }
+        
+        m_handlers = new HandlerManager[0];
         m_fieldRegistration = new HashMap();
+        m_methodRegistration = new HashMap();
         m_clazz = null;
-        m_pojoObjects = new Object[0];
+        m_inTransition = false;
         m_instanceListeners.clear();
     }
     
@@ -328,10 +280,16 @@
 
         // Cleaning
         m_state = DISPOSED;
-        m_handlers = new Handler[0];
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].dispose();
+        }
+        
+        m_handlers = new HandlerManager[0];
         m_fieldRegistration = new HashMap();
+        m_methodRegistration = new HashMap();
         m_clazz = null;
-        m_pojoObjects = new Object[0];
+        m_inTransition = false;
         m_instanceListeners.clear();
     }
     
@@ -342,7 +300,7 @@
      * the second call is stored and executed after the first one is finished.
      * @param state : the new state
      */
-    private synchronized void setState(int state) {
+    public void setState(int state) {
         if (m_inTransition) {
             m_stateQueue.add(new Integer(state)); 
             return;
@@ -351,18 +309,10 @@
         if (m_state != state) {
             m_inTransition = true;
 
-            // Log the state change
-            if (state == INVALID) {
-                m_factory.getLogger().log(Logger.INFO, "[" + m_name + "]  State -> INVALID");
-            }
-            if (state == VALID) {
-                m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] State -> VALID");
-            }
-
             // The state changed call the handler stateChange method
             m_state = state;
             for (int i = m_handlers.length - 1; i > -1; i--) {
-                m_handlers[i].stateChanged(state);
+                m_handlers[i].getHandler().stateChanged(state);
             }
             
             for (int i = 0; i < m_instanceListeners.size(); i++) {
@@ -401,7 +351,9 @@
      * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
     public void addInstanceStateListener(InstanceStateListener listener) {
-        m_instanceListeners.add(listener);
+        synchronized (m_instanceListeners) {
+            m_instanceListeners.add(listener);
+        }
     }
 
     /**
@@ -410,13 +362,11 @@
      * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
     public void removeInstanceStateListener(InstanceStateListener listener) {
-        m_instanceListeners.remove(listener);
+        synchronized (m_instanceListeners) {
+            m_instanceListeners.remove(listener);
+        }
     }
 
-    // ===================== end Lifecycle management =====================
-
-    // ================== Class & Instance management ===================
-
     /**
      * Get the factory which create the current instance.
      * @return the factory of the component
@@ -450,7 +400,7 @@
      * Add an instance to the created instance list.
      * @param o : the instance to add
      */
-    private void addInstance(Object o) {
+    private synchronized void addInstance(Object o) {
         for (int i = 0; (m_pojoObjects != null) && (i < m_pojoObjects.length); i++) {
             if (m_pojoObjects[i] == o) {
                 return;
@@ -468,12 +418,20 @@
     }
 
     /**
-     * Remove an instance from the created instance list.
-     * The instance will be destroyed by the garbage collector.
-     * 
-     * @param o : the instance to remove
+     * Get the array of object created by the instance.
+     * @return the created instance of the component instance.
      */
-    private void removeInstance(Object o) {
+    public Object[] getPojoObjects() {
+        return m_pojoObjects;
+    }
+
+    /**
+     * Delete the created instance (remove it from the list, to allow the
+     * garbage collector to eat the instance).
+     * 
+     * @param o : the instance to delete
+     */
+    public synchronized void deletePojoObject(Object o) {
         int idx = -1;
         for (int i = 0; i < m_pojoObjects.length; i++) {
             if (m_pojoObjects[i] == o) {
@@ -497,24 +455,6 @@
     }
 
     /**
-     * Get the array of object created by the instance.
-     * @return the created instance of the component instance.
-     */
-    public Object[] getPojoObjects() {
-        return m_pojoObjects;
-    }
-
-    /**
-     * Delete the created instance (remove it from the list, to allow the
-     * garbage collector to eat the instance).
-     * 
-     * @param o : the instance to delete
-     */
-    public void deletePojoObject(Object o) {
-        removeInstance(o);
-    }
-
-    /**
      * Create an instance of the component. This method need to be called one
      * time only for singleton provided service
      * 
@@ -527,7 +467,6 @@
         }
         Object instance = null;
         try {
-
             // Try to find if there is a constructor with a bundle context as
             // parameter :
             try {
@@ -554,17 +493,20 @@
             m_factory.getLogger().log(Logger.ERROR,
                     "[" + m_name + "] createInstance -> The Component Instance is not accessible (security reason) : " + e.getMessage());
         } catch (InvocationTargetException e) {
-            m_factory.getLogger().log(Logger.ERROR,
-                    "[" + m_name + "] createInstance -> Cannot invoke the constructor method (illegal target) : " + e.getMessage());
+            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor method (illegal target) : " + e.getMessage());
+            e.printStackTrace();
         } catch (NoSuchMethodException e) {
             m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
         }
+        if (instance == null) {
+            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot create the instance");
+        }
 
         // Register the new instance
         addInstance(instance);
         // Call createInstance on Handlers :
         for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].createInstance(instance);
+            ((PrimitiveHandler) m_handlers[i].getHandler()).objectCreated(instance);
         }
         return instance;
     }
@@ -574,7 +516,7 @@
      * If no object created, create and return one object.
      * @return the instance of the component instance to use for singleton component
      */
-    public Object getPojoObject() {
+    public synchronized Object getPojoObject() {
         if (m_pojoObjects.length == 0) {
             createPojoObject();
         }
@@ -592,30 +534,6 @@
         return m_clazz;
     }
 
-    // ================== end Class & Instance management ================
-
-    // ======================== Handlers Management ======================
-
-    /**
-     * Register the given handler to the current instance manager.
-     * 
-     * @param h : the handler to register
-     */
-    public void register(Handler h) {
-        for (int i = 0; (m_handlers != null) && (i < m_handlers.length); i++) {
-            if (m_handlers[i] == h) {
-                return;
-            }
-        }
-
-        if (m_handlers != null) {
-            Handler[] newList = new Handler[m_handlers.length + 1];
-            System.arraycopy(m_handlers, 0, newList, 0, m_handlers.length);
-            newList[m_handlers.length] = h;
-            m_handlers = newList;
-        }
-    }
-
     /**
      * Register an handler. The handler will be notified of event on each field
      * given in the list.
@@ -624,19 +542,18 @@
      * @param fields : the field metadata list
      * @param methods : the method metadata list
      */
-    public void register(Handler h, FieldMetadata[] fields, MethodMetadata[] methods) {
-        register(h);
+    public void register(PrimitiveHandler h, FieldMetadata[] fields, MethodMetadata[] methods) {
         for (int i = 0; fields != null && i < fields.length; i++) {
             if (m_fieldRegistration.get(fields[i].getFieldName()) == null) {
-                m_fieldRegistration.put(fields[i].getFieldName(), new Handler[] { h });
+                m_fieldRegistration.put(fields[i].getFieldName(), new PrimitiveHandler[] { h });
             } else {
-                Handler[] list = (Handler[]) m_fieldRegistration.get(fields[i].getFieldName());
+                PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fields[i].getFieldName());
                 for (int j = 0; j < list.length; j++) {
                     if (list[j] == h) {
                         return;
                     }
                 }
-                Handler[] newList = new Handler[list.length + 1];
+                PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
                 System.arraycopy(list, 0, newList, 0, list.length);
                 newList[list.length] = h;
                 m_fieldRegistration.put(fields[i].getFieldName(), newList);
@@ -644,15 +561,15 @@
         }
         for (int i = 0; methods != null && i < methods.length; i++) {
             if (m_methodRegistration.get(methods[i].getMethodIdentifier()) == null) {
-                m_methodRegistration.put(methods[i].getMethodIdentifier(), new Handler[] { h });
+                m_methodRegistration.put(methods[i].getMethodIdentifier(), new PrimitiveHandler[] { h });
             } else {
-                Handler[] list = (Handler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
+                PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
                 for (int j = 0; j < list.length; j++) {
                     if (list[j] == h) {
                         return;
                     }
                 }
-                Handler[] newList = new Handler[list.length + 1];
+                PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
                 System.arraycopy(list, 0, newList, 0, list.length);
                 newList[list.length] = h;
                 m_methodRegistration.put(methods[i].getMethodIdentifier(), newList);
@@ -669,12 +586,12 @@
      * @param fields : the field metadata list
      * @param methods : the method metadata list
      */
-    public void unregister(Handler h, FieldMetadata[] fields, MethodMetadata[] methods) {
+    public void unregister(PrimitiveHandler h, FieldMetadata[] fields, MethodMetadata[] methods) {
         for (int i = 0; i < fields.length; i++) {
             if (m_fieldRegistration.get(fields[i].getFieldName()) == null) {
                 break;
             } else {
-                Handler[] list = (Handler[]) m_fieldRegistration.get(fields[i].getFieldName());
+                PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fields[i].getFieldName());
                 int idx = -1;
                 for (int j = 0; j < list.length; j++) {
                     if (list[j] == h) {
@@ -685,9 +602,9 @@
 
                 if (idx >= 0) {
                     if ((list.length - 1) == 0) {
-                        list = new Handler[0];
+                        list = new PrimitiveHandler[0];
                     } else {
-                        Handler[] newList = new Handler[list.length - 1];
+                        PrimitiveHandler[] newList = new PrimitiveHandler[list.length - 1];
                         System.arraycopy(list, 0, newList, 0, idx);
                         if (idx < newList.length) {
                             System.arraycopy(list, idx + 1, newList, idx, newList.length - idx);
@@ -702,7 +619,7 @@
             if (m_methodRegistration.get(methods[i].getMethodIdentifier()) == null) {
                 break;
             } else {
-                Handler[] list = (Handler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
+                PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
                 int idx = -1;
                 for (int j = 0; j < list.length; j++) {
                     if (list[j] == h) {
@@ -713,9 +630,9 @@
 
                 if (idx >= 0) {
                     if ((list.length - 1) == 0) {
-                        list = new Handler[0];
+                        list = new PrimitiveHandler[0];
                     } else {
-                        Handler[] newList = new Handler[list.length - 1];
+                        PrimitiveHandler[] newList = new PrimitiveHandler[list.length - 1];
                         System.arraycopy(list, 0, newList, 0, idx);
                         if (idx < newList.length) {
                             System.arraycopy(list, idx + 1, newList, idx, newList.length - idx);
@@ -727,34 +644,6 @@
             }
         }
     }
-
-    /**
-     * Unregister the given handler.
-     * 
-     * @param h : the handler to unregister
-     */
-    public void unregister(Handler h) {
-        int idx = -1;
-        for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i] == h) {
-                idx = i;
-                break;
-            }
-        }
-
-        if (idx >= 0) {
-            if ((m_handlers.length - 1) == 0) {
-                m_handlers = new Handler[0];
-            } else {
-                Handler[] newList = new Handler[m_handlers.length - 1];
-                System.arraycopy(m_handlers, 0, newList, 0, idx);
-                if (idx < newList.length) {
-                    System.arraycopy(m_handlers, idx + 1, newList, idx, newList.length - idx);
-                }
-                m_handlers = newList;
-            }
-        }
-    }
     
     public Set getRegistredFields() {
         return m_fieldRegistration.keySet();
@@ -772,13 +661,13 @@
      * @param fieldName : the field name on which the GETFIELD instruction is
      * called
      * @param initialValue : the value of the field in the code
-     * @return the value decided by the last asked handler (throw a warining if
+     * @return the value decided by the last asked handler (throw a warning if
      * two fields decide two different values)
      */
-    public Object getterCallback(String fieldName, Object initialValue) {
+    public synchronized Object getterCallback(String fieldName, Object initialValue) {
         Object result = null;
         // Get the list of registered handlers
-        Handler[] list = (Handler[]) m_fieldRegistration.get(fieldName);
+        PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
         for (int i = 0; list != null && i < list.length; i++) {
             Object handlerResult = list[i].getterCallback(fieldName, initialValue);
             if (handlerResult != initialValue) {
@@ -797,8 +686,8 @@
      * Dispatch entry method event on registered handler.
      * @param methodId : method id
      */
-    public void entryCallback(String methodId) {
-        Handler[] list = (Handler[]) m_methodRegistration.get(methodId);
+    public synchronized void entryCallback(String methodId) {
+        PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].entryCallback(methodId);
         }
@@ -811,8 +700,8 @@
      * @param methodId : method id
      * @param e : returned object.
      */
-    public void exitCallback(String methodId, Object e) {
-        Handler[] list = (Handler[]) m_methodRegistration.get(methodId);
+    public synchronized void exitCallback(String methodId, Object e) {
+        PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].exitCallback(methodId, e);
         }
@@ -826,9 +715,9 @@
      * called
      * @param objectValue : the value of the field
      */
-    public void setterCallback(String fieldName, Object objectValue) {
+    public synchronized void setterCallback(String fieldName, Object objectValue) {
         // Get the list of registered handlers
-        Handler[] list = (Handler[]) m_fieldRegistration.get(fieldName);
+        PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
 
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].setterCallback(fieldName, objectValue);
@@ -853,29 +742,6 @@
     }
 
     /**
-     * Check the state of all handlers.
-     */
-    public void checkInstanceState() {
-        if (!isStarted()) { return; }
-        
-        boolean isValid = true;
-        for (int i = 0; i < m_handlers.length; i++) {
-            boolean b = m_handlers[i].isValid();
-            isValid = isValid && b;
-        }
-     
-        // Update the component state if necessary
-        if (!isValid && m_state == VALID) {
-            // Need to update the state to UNRESOLVED
-            setState(INVALID);
-            return;
-        }
-        if (isValid && m_state == INVALID) {
-            setState(VALID);
-        }
-    }
-
-    /**
      * Get the instance name.
      * @return the instance name.
      * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
@@ -891,7 +757,7 @@
      */
     public void reconfigure(Dictionary configuration) {
         for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].reconfigure(configuration);
+            m_handlers[i].getHandler().reconfigure(configuration);
         }
     }
 
@@ -903,6 +769,34 @@
         return m_className;
     }
 
-    // ======================= end Handlers Management =====================
-
+    /**
+     * State Change listener callback.
+     * This method is notified at each time a plugged handler becomes invalid.
+     * @param instance : changing instance 
+     * @param newState : new state
+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
+     */
+    public synchronized void stateChanged(ComponentInstance instance, int newState) {
+        if (m_state <= STOPPED) { return; }
+        
+        // Update the component state if necessary
+        if (newState == INVALID && m_state == VALID) {
+            // Need to update the state to UNRESOLVED
+            setState(INVALID);
+            return;
+        }
+        if (newState == VALID && m_state == INVALID) {
+            // An handler becomes valid => check if all handlers are valid
+            for (int i = 0; i < m_handlers.length; i++) {
+                if (m_handlers[i].getState() != VALID) { return; }
+            }
+            setState(VALID);
+            return;
+        }
+        
+        if (newState == DISPOSED) {
+            dispose();
+        }
+        
+    }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
new file mode 100644
index 0000000..7e90e43
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
@@ -0,0 +1,60 @@
+/* 

+ * 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;

+

+import java.util.List;

+

+/**

+ * Missing Handler Exception.

+ * This exception occurs when an handler is missing to build an instance.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class MissingHandlerException extends Exception {

+    

+    /**

+     * Serialization Id. 

+     */

+    private static final long serialVersionUID = 5047792897590881478L;

+    

+    /**

+     * Message. 

+     */

+    private String m_message;

+    

+    /**

+     * Constructor.

+     * @param missing : list of missing handlers.

+     */

+    public MissingHandlerException(List missing) {

+        m_message = "Missing handlers : ";

+        for (int i = 0; i < missing.size(); i++) {

+            m_message += (String) missing.get(i) + " ";

+        }

+    }

+    

+    /**

+     * Get the error message.

+     * @return : the error message

+     * @see java.lang.Throwable#getMessage()

+     */

+    public String getMessage() {

+        return m_message;

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
index 2cca0d6..45034a2 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
@@ -18,10 +18,17 @@
  */

 package org.apache.felix.ipojo;

 

+import java.io.File;

+import java.io.InputStream;

 import java.util.Dictionary;

 

 import org.apache.felix.ipojo.composite.ServiceReferenceImpl;

+import org.osgi.framework.Bundle;

 import org.osgi.framework.BundleContext;

+import org.osgi.framework.BundleException;

+import org.osgi.framework.BundleListener;

+import org.osgi.framework.Filter;

+import org.osgi.framework.FrameworkListener;

 import org.osgi.framework.InvalidSyntaxException;

 import org.osgi.framework.ServiceListener;

 import org.osgi.framework.ServiceReference;

@@ -56,12 +63,12 @@
     /**

      * Global service registry.

      */

-    private BundleContext m_global;

+    public BundleContext m_global;

     

     /**

      * Local (Composite) Service Registry.

      */

-    private ServiceContext m_local;

+    public ServiceContext m_local;

     

     /**

      * Resolving policy.

@@ -294,4 +301,125 @@
         }

     }

 

+    /**

+     * Add a bundle listener.

+     * Delegate on the global bundle context.

+     * @param arg0 : bundle listener to add

+     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)

+     */

+    public void addBundleListener(BundleListener arg0) {

+        m_global.addBundleListener(arg0);

+    }

+

+    /**

+     * Add a framework listener.

+     * Delegate on the global bundle context.

+     * @param arg0 : framework listener to add.

+     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)

+     */

+    public void addFrameworkListener(FrameworkListener arg0) {

+        m_global.addFrameworkListener(arg0);

+    }

+

+    /**

+     * Create a LDAP filter.

+     * @param arg0 : String-form of the filter

+     * @return the created filter object

+     * @throws InvalidSyntaxException : if the given argument is not a valid against the LDAP grammar.

+     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)

+     */

+    public Filter createFilter(String arg0) throws InvalidSyntaxException {

+        return m_global.createFilter(arg0);

+    }

+

+    /**

+     * Get the current bundle.

+     * @return the current bundle

+     * @see org.osgi.framework.BundleContext#getBundle()

+     */

+    public Bundle getBundle() {

+        return m_global.getBundle();

+    }

+

+    /**

+     * Get the bundle object with the given id.

+     * @param id : bundle id

+     * @return the bundle object

+     * @see org.osgi.framework.BundleContext#getBundle(long)

+     */

+    public Bundle getBundle(long id) {

+        return m_global.getBundle(id);

+    }

+

+    /**

+     * Get installed bundles.

+     * @return the list of installed bundles

+     * @see org.osgi.framework.BundleContext#getBundles()

+     */

+    public Bundle[] getBundles() {

+        return m_global.getBundles();

+    }

+

+

+    /**

+     * Get a data file.

+     * @param filename : File name.

+     * @return the File object

+     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)

+     */

+    public File getDataFile(String filename) {

+        return m_global.getDataFile(filename);

+    }

+

+    /**

+     * Get a property value.

+     * @param key : key of the asked property

+     * @return the property value (object) or null if no property are associated with the given key

+     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)

+     */

+    public String getProperty(String key) {

+        return m_global.getProperty(key);

+    }

+

+    /**

+     * Install a bundle.

+     * @param location : URL of the bundle to install

+     * @return the installed bundle

+     * @throws BundleException : if the bundle cannot be installed correctly

+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)

+     */

+    public Bundle installBundle(String location) throws BundleException {

+        return m_global.installBundle(location);

+    }

+

+    /**

+     * Install a bundle.

+     * @param location : URL of the bundle to install

+     * @param input : 

+     * @return the installed bundle

+     * @throws BundleException : if the bundle cannot be installed correctly

+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)

+     */

+    public Bundle installBundle(String location, InputStream input) throws BundleException {

+        return m_global.installBundle(location, input);

+    }

+

+    /**

+     * Remove a bundle listener.

+     * @param listener : the listener to remove

+     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)

+     */

+    public void removeBundleListener(BundleListener listener) {

+        m_global.removeBundleListener(listener);

+    }

+

+    /**

+     * Remove a framework listener.

+     * @param listener : the listener to remove

+     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)

+     */

+    public void removeFrameworkListener(FrameworkListener listener) {

+        m_global.removeFrameworkListener(listener);

+    }

+

 }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
new file mode 100644
index 0000000..cbfad6e
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
@@ -0,0 +1,124 @@
+/* 

+ * 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;

+

+/**

+* Abstract class to extends for primitive handler.

+* 

+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+*/

+public abstract class PrimitiveHandler extends Handler {

+    

+    /**

+     * "Primitive" Handler type (value).

+     */

+    public static final String HANDLER_TYPE = "primitive";

+    

+    /**

+     * Reference on the instance manager.

+     */

+    private InstanceManager m_manager;

+    

+    /**

+     * Attach the current handler to the given instance.

+     * @param im ! the instance on which the current handler will be attached.

+     * @see org.apache.felix.ipojo.Handler#attach(org.apache.felix.ipojo.ComponentInstance)

+     */

+    protected final void attach(ComponentInstance im) {

+        m_manager = (InstanceManager) im;

+    }

+    

+    public InstanceManager getInstanceManager() {

+        return m_manager;

+    }

+    

+    /**

+     * Log method.

+     * @param level : message level (Logger class constant)

+     * @param message : message to log

+     */

+    public void log(int level, String message) {

+        m_manager.getFactory().getLogger().log(level, message);

+    }

+    

+    /**

+     * Log method.

+     * @param level : message level (Logger class constant)

+     * @param message : message to log

+     * @param ex : exception to attach to the message

+     */

+    public void log(int level, String message, Throwable ex) {

+        m_manager.getFactory().getLogger().log(level, message, ex);

+    }

+    

+    /**

+     * Get a plugged handler of the same container.

+     * This method must be call only in the start method (or after). 

+     * In the configure method, this method can not return a consistent

+     * result as all handlers are not plugged. 

+     * @param name : name of the handler to find (class name or qualified handler name (ns:name)). 

+     * @return the handler object or null if the handler is not found.

+     */

+    public final Handler getHandler(String name) {

+        return m_manager.getHandler(name);

+    }

+    

+    /**

+     * This method is called when a PUTFIELD operation is detected.

+     * @param fieldName : the field name

+     * @param value : the value passed to the field

+     */

+    public void setterCallback(String fieldName, Object value) { }

+

+    /**

+     * This method is called when a GETFIELD operation is detected.

+     * @param fieldName : the field name

+     * @param value : the value passed to the field (by the previous handler)

+     * @return : the managed value of the field

+     */

+    public Object getterCallback(String fieldName, Object value) {

+        return value;

+    }

+    

+    /**

+     * This method is called when the execution enter in a method.

+     * @param methodId : the method identifier

+     */

+    public void entryCallback(String methodId) { }

+

+    /**

+     * This method is called when the execution exit a method (before a return or a throw).

+     * If the given returned object is an instance of Exception, this means that the method throwed this exception.

+     * If the given returned object is null, either the method is void, either it returns null.

+     * You must not modified the returned object.

+     * @param methodId : the method identifier

+     * @param returnedObj : the returned object (boxed for primitive type)

+     */

+    public void exitCallback(String methodId, Object returnedObj) { }

+    

+    /**

+     * This method is called when an instance of the component is created, but

+     * before someone can use it.

+     * @param instance : the created instance

+     */

+    public void objectCreated(Object instance) { }

+    

+    

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
index 110cd8f..ff951c5 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
@@ -20,6 +20,7 @@
 
 import java.util.Dictionary;
 
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
@@ -31,7 +32,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public interface ServiceContext {
+public interface ServiceContext extends BundleContext {
 
     /**
      * Add a service listener.
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
index e1f5515..01ad8c7 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
@@ -18,12 +18,14 @@
  */
 package org.apache.felix.ipojo.architecture;
 
+import java.util.List;
+
+import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 
 /**
- * Component Type information.
- * 
+ * Component Type description.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class ComponentDescription {
@@ -47,32 +49,43 @@
      * Get the name of this component type.
      */
     private String m_name;
-    
+
     /**
      * Bundle Id of the bundle containing this type.
      */
     private long m_bundleId;
 
     /**
-     * Constructor.
-     * 
-     * @param name : name of the component type (factory name).
-     * @param className : implementation class.
-     * @param bundle : bundle id.
+     * State of the factory.
      */
-    public ComponentDescription(String name, String className, long bundle) {
+    private int m_state;
+
+    /**
+     * Required handler list.
+     */
+    private List m_rh;
+
+    /**
+     * Missing handler list.
+     */
+    private List m_mh;
+
+    /**
+     * Constructor.
+     * @param name : name.
+     * @param className : implementation class or "composite"
+     * @param state : state of the type (valid or invalid)
+     * @param rh : required handler list
+     * @param mh : missing handler list
+     * @param bundle : bundle containing the type
+     */
+    public ComponentDescription(String name, String className, int state, List rh, List mh, long bundle) {
         m_name = name;
         m_className = className;
         m_bundleId = bundle;
-    }
-
-    /**
-     * Constructor for composite.
-     * 
-     * @param name : name of the component type (factory name).
-     */
-    public ComponentDescription(String name) {
-        m_name = name;
+        m_state = state;
+        m_rh = rh;
+        m_mh = mh;
     }
 
     /**
@@ -94,27 +107,33 @@
 
     /**
      * Get component-type properties.
-     * @return the list of configuration properties accepted by the component type
-     * type.
+     * @return the list of configuration properties accepted by the component type type.
      */
     public PropertyDescription[] getProperties() {
         return m_properties;
     }
 
     /**
+     * Add a String property in the component type.
+     * @param name : property name.
+     * @param value : property value.
+     */
+    public void addProperty(String name, String value) {
+        PropertyDescription pd = new PropertyDescription(name, String.class.getName(), value);
+        addProperty(pd);
+    }
+
+    /**
      * Add a configuration properties to the component type.
-     * 
      * @param pd : the property to add
      */
     public void addProperty(PropertyDescription pd) {
-        if (pd.getName().equals("name")) {
+        if ("name".equals(pd.getName())) {
             pd = new PropertyDescription(pd.getName(), pd.getType(), null); // Erase the instance name
         }
-        
+
         for (int i = 0; i < m_properties.length; i++) {
-            if (m_properties[i].getName().equals(pd.getName())) {
-                return;
-            }
+            if (m_properties[i].getName().equals(pd.getName())) { return; }
         }
 
         PropertyDescription[] newProps = new PropertyDescription[m_properties.length + 1];
@@ -133,8 +152,7 @@
 
     /**
      * Add a provided service to the component type.
-     * @param serviceSpecification : the provided service to add (interface
-     * name)
+     * @param serviceSpecification : the provided service to add (interface name)
      */
     public void addProvidedServiceSpecification(String serviceSpecification) {
         String[] newSs = new String[m_providedServiceSpecification.length + 1];
@@ -150,29 +168,43 @@
     public String getName() {
         return m_name;
     }
-    
+
     /**
      * Get the component type description.
      * @return : the description
      */
     public Element getDescription() {
         Element desc = new Element("Factory", "");
-        
+
         desc.addAttribute(new Attribute("name", m_name));
         desc.addAttribute(new Attribute("bundle", "" + m_bundleId));
-        
+
         if (m_className != null) {
             desc.addAttribute(new Attribute("Implementation-Class", m_className));
         } else {
             desc.addAttribute(new Attribute("Composite", "true"));
         }
-        
+
+        String state = "valid";
+        if (m_state == Factory.INVALID) {
+            state = "invalid";
+        }
+        desc.addAttribute(new Attribute("state", state));
+
+        // Display required & missing handlers
+        Element rh = new Element("RequiredHandlers", "");
+        rh.addAttribute(new Attribute("list", m_rh.toString()));
+        Element mh = new Element("MissingHandlers", "");
+        mh.addAttribute(new Attribute("list", m_mh.toString()));
+        desc.addElement(rh);
+        desc.addElement(mh);
+
         for (int i = 0; i < m_providedServiceSpecification.length; i++) {
             Element prov = new Element("provides", "");
             prov.addAttribute(new Attribute("specification", m_providedServiceSpecification[i]));
             desc.addElement(prov);
         }
-        
+
         for (int i = 0; i < m_properties.length; i++) {
             Element prop = new Element("property", "");
             prop.addAttribute(new Attribute("name", m_properties[i].getName()));
@@ -184,7 +216,7 @@
             }
             desc.addElement(prop);
         }
-        
+
         return desc;
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
index d9cd6f5..8847575 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.ipojo.architecture;
 
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.Handler;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 
@@ -41,12 +43,21 @@
     /**
      * Constructor.
      * 
-     * @param name : handler name
-     * @param isValid : is the handler valid
+     * @param h : handler.
      */
-    public HandlerDescription(String name, boolean isValid) {
-        m_handlerName = name;
-        m_isValid = isValid;
+    public HandlerDescription(Handler h) {
+        m_handlerName = h.getClass().getName();
+        m_isValid = h.isValid();
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param h : composite handler.
+     */
+    public HandlerDescription(CompositeHandler h) {
+        m_handlerName = h.getClass().getName();
+        m_isValid = h.isValid();
     }
 
     /**
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
index 99e3ec5..5040d94 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
@@ -150,8 +150,7 @@
         // Verify that the dependency description is not already in the array.
         for (int i = 0; i < m_containedInstances.length; i++) {
             if (m_containedInstances[i] == inst) {
-                return; // NOTHING TO DO, the description is already in the
-                        // array
+                return; // NOTHING TO DO, the description is already in the array
             }
         }
         // The component Description is not in the array, add it
@@ -232,10 +231,12 @@
             instance.addElement(obj);
         }
         // Contained instance (exposing architecture) (empty if primitive)
-        for (int i = 0; i < m_containedInstances.length; i++) {
+        if (m_containedInstances.length > 0) {
             Element inst = new Element("ContainedInstances", "");
-            inst.addElement(m_containedInstances[i].getDescription());
-            instance.addElement(inst);
+            for (int i = 0; i < m_containedInstances.length; i++) {
+                inst.addElement(m_containedInstances[i].getDescription());
+                instance.addElement(inst);
+            }
         }
         return instance;
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
index 17ae520..1819862 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.ipojo.composite;
 
+import java.io.File;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.List;
@@ -27,10 +29,15 @@
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.IPojoContext;
 import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
@@ -41,7 +48,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class CompositeServiceContext implements ServiceContext, ServiceListener {
+public class CompositeServiceContext implements ServiceContext, TrackerCustomizer {
 
     /**
      * Structure storing the reference, the factory and the registration.
@@ -85,6 +92,11 @@
      * Global service context.
      */
     private BundleContext m_global;
+    
+    /**
+     * Tracker tracking Factories to import.
+     */
+    private Tracker m_tracker;
 
     /**
      * Constructor. This constructor instantiate a service registry with the
@@ -225,34 +237,18 @@
     }
 
     /**
-     * Initiate the factory list.
-     */
-    private void importFactories() {
-        try {
-            ServiceReference[] refs = m_global.getServiceReferences(Factory.class.getName(), null);
-            if (refs != null) {
-                for (int i = 0; i < refs.length; i++) {
-                    importFactory(refs[i]);
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace(); // Should not happen
-        }
-    }
-
-    /**
      * Import a factory form the parent to the internal registry.
      * 
      * @param ref : the reference of the factory to import.
      */
-    private void importFactory(ServiceReference ref) {
+    private void importFactory(ServiceReference ref) {        
         Record rec = new Record();
         m_factories.add(rec);
         Dictionary dict = new Properties();
         for (int j = 0; j < ref.getPropertyKeys().length; j++) {
             dict.put(ref.getPropertyKeys()[j], ref.getProperty(ref.getPropertyKeys()[j]));
         }
-        rec.m_fact = new FactoryProxy((Factory) m_global.getService(ref), this);
+        rec.m_fact = new FactoryProxy((Factory) m_tracker.getService(ref), this);
         rec.m_reg = registerService(Factory.class.getName(), rec.m_fact, dict);
         rec.m_ref = ref;
     }
@@ -266,9 +262,11 @@
         for (int i = 0; i < m_factories.size(); i++) {
             Record rec = (Record) m_factories.get(i);
             if (rec.m_ref == ref) {
-                rec.m_reg.unregister();
-                rec.m_fact = null;
-                m_global.ungetService(rec.m_ref);
+                if (rec.m_reg != null) {
+                    rec.m_reg.unregister();
+                    rec.m_fact = null;
+                }
+                m_tracker.ungetService(rec.m_ref);
                 m_factories.remove(rec);
                 return;
             }
@@ -278,44 +276,22 @@
     /**
      * Start the registry management.
      */
-    public synchronized void start() {
-        importFactories();
-        try {
-            m_global.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")");
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace(); // Should not happen
-        }
+    public void start() {
+        m_tracker = new Tracker(m_global, Factory.class.getName(), this);
+        m_tracker.open();
     }
 
     /**
      * Stop the registry management.
      */
     public synchronized void stop() {
-        m_global.removeServiceListener(this);
+        m_tracker.close();
         m_registry.reset();
         for (int i = 0; i < m_factories.size(); i++) {
             Record rec = (Record) m_factories.get(i);
             removeFactory(rec.m_ref);
         }
-    }
-
-    /**
-     * Service Listener implementation.
-     * @param event : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent event) {
-        if (event.getType() == ServiceEvent.REGISTERED) {
-            if (!containsRef(event.getServiceReference())) {
-                importFactory(event.getServiceReference());
-            }
-            return;
-        }
-        if (event.getType() == ServiceEvent.UNREGISTERING) {
-            if (containsRef(event.getServiceReference())) {
-                removeFactory(event.getServiceReference());
-            }
-        }
+        m_tracker = null;
     }
 
     /**
@@ -333,4 +309,172 @@
         }
         return false;
     }
+
+    /**
+     * Add a bundle listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : bundle listener to add
+     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void addBundleListener(BundleListener arg0) {
+        m_global.addBundleListener(arg0);
+    }
+
+    /**
+     * Add a framework listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : framework listener to add.
+     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void addFrameworkListener(FrameworkListener arg0) {
+        m_global.addFrameworkListener(arg0);
+    }
+
+    /**
+     * Create a LDAP filter.
+     * @param arg0 : String-form of the filter
+     * @return the created filter object
+     * @throws InvalidSyntaxException : if the given argument is not a valid against the LDAP grammar.
+     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
+     */
+    public Filter createFilter(String arg0) throws InvalidSyntaxException {
+        return m_global.createFilter(arg0);
+    }
+
+    /**
+     * Get the current bundle.
+     * @return the current bundle
+     * @see org.osgi.framework.BundleContext#getBundle()
+     */
+    public Bundle getBundle() {
+        return m_global.getBundle();
+    }
+
+    /**
+     * Get the bundle object with the given id.
+     * @param id : bundle id
+     * @return the bundle object
+     * @see org.osgi.framework.BundleContext#getBundle(long)
+     */
+    public Bundle getBundle(long id) {
+        return m_global.getBundle(id);
+    }
+
+    /**
+     * Get installed bundles.
+     * @return the list of installed bundles
+     * @see org.osgi.framework.BundleContext#getBundles()
+     */
+    public Bundle[] getBundles() {
+        return m_global.getBundles();
+    }
+
+
+    /**
+     * Get a data file.
+     * @param filename : File name.
+     * @return the File object
+     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
+     */
+    public File getDataFile(String filename) {
+        return m_global.getDataFile(filename);
+    }
+
+    /**
+     * Get a property value.
+     * @param key : key of the asked property
+     * @return the property value (object) or null if no property are associated with the given key
+     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
+     */
+    public String getProperty(String key) {
+        return m_global.getProperty(key);
+    }
+
+    /**
+     * Install a bundle.
+     * @param location : URL of the bundle to install
+     * @return the installed bundle
+     * @throws BundleException : if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
+     */
+    public Bundle installBundle(String location) throws BundleException {
+        return m_global.installBundle(location);
+    }
+
+    /**
+     * Install a bundle.
+     * @param location : URL of the bundle to install
+     * @param input : 
+     * @return the installed bundle
+     * @throws BundleException : if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
+     */
+    public Bundle installBundle(String location, InputStream input) throws BundleException {
+        return m_global.installBundle(location, input);
+    }
+
+    /**
+     * Remove a bundle listener.
+     * @param listener : the listener to remove
+     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void removeBundleListener(BundleListener listener) {
+        m_global.removeBundleListener(listener);
+    }
+
+    /**
+     * Remove a framework listener.
+     * @param listener : the listener to remove
+     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void removeFrameworkListener(FrameworkListener listener) {
+        m_global.removeFrameworkListener(listener);
+    }
+
+    /**
+     * A new factory is detected.
+     * @param reference : service reference
+     * @return true if not already imported.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        if (!containsRef(reference)) {
+            importFactory(reference);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * An imported factory is modified.
+     * @param reference : modified reference
+     * @param service : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+        for (int i = 0; i < m_factories.size(); i++) {
+            Record rec = (Record) m_factories.get(i);
+            if (rec.m_ref == reference) {
+                Dictionary dict = new Properties();
+                for (int j = 0; j < reference.getPropertyKeys().length; j++) {
+                    dict.put(reference.getPropertyKeys()[j], reference.getProperty(reference.getPropertyKeys()[j]));
+                }
+                rec.m_reg.setProperties(dict);
+                return;
+            }
+        }
+    }
+
+    /**
+     * An imported factory disappears.
+     * @param reference : reference
+     * @param service : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        if (containsRef(reference)) {
+            removeFactory(reference);
+        }
+        
+    }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
index 40d8e03..283b1e4 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
@@ -19,16 +19,20 @@
 package org.apache.felix.ipojo.composite;
 
 import java.util.Dictionary;
+import java.util.List;
 
 import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.FactoryStateListener;
+import org.apache.felix.ipojo.MissingHandlerException;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.metadata.Element;
 
 /**
  * Bridge representing a Factory inside a composition.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class FactoryProxy implements Factory {
@@ -45,7 +49,6 @@
 
     /**
      * Constructor.
-     * 
      * @param fact : the targeted factory.
      * @param s : the service context to target.
      */
@@ -56,35 +59,36 @@
 
     /**
      * Create an instance manager (i.e. component type instance).
-     * 
      * @param configuration : the configuration properties for this component.
      * @return the created instance manager.
      * @throws UnacceptableConfiguration : when a given configuration is not valid.
+     * @throws MissingHandlerException : occurs when the creation failed due to a missing handler (the factory should be invalid)
+     * @throws ConfigurationException : occurs when the creation failed due to a configuration issue
      * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
      */
-    public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration {
+    public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
         return m_delegate.createComponentInstance(configuration, m_context);
     }
 
     /**
      * Create an instance manager (i.e. component type instance). This has these
      * service interaction in the scope given in argument.
-     * 
      * @param configuration : the configuration properties for this component.
      * @param serviceContext : the service context of the component.
      * @return the created instance manager.
-     * @throws UnacceptableConfiguration : when the given configuration isnot valid.
+     * @throws UnacceptableConfiguration : when the given configuration is not valid.
+     * @throws MissingHandlerException : when at least one handler is missing. 
+     * @throws ConfigurationException : when an issue occurs during the oconfiguration of the instance.
      * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary,
      * org.apache.felix.ipojo.ServiceContext)
      */
-    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration {
+    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
         return m_delegate.createComponentInstance(configuration, serviceContext);
     }
 
     /**
      * Get the component type information containing provided service,
      * configuration properties ...
-     * 
      * @return the component type information.
      * @see org.apache.felix.ipojo.Factory#getDescription()
      */
@@ -104,7 +108,6 @@
     /**
      * Check if the given configuration is acceptable as a configuration of a
      * component instance.
-     * 
      * @param conf : the configuration to test
      * @return true if the configuration is acceptable
      * @see org.apache.felix.ipojo.Factory#isAcceptable(java.util.Dictionary)
@@ -116,14 +119,46 @@
     /**
      * Reconfigure an instance already created. This configuration need to have
      * the name property to identify the instance.
-     * 
      * @param conf : the configuration to reconfigure the instance.
      * @throws UnacceptableConfiguration : if the given configuration is not
      * consistent for the targeted instance.
+     * @throws MissingHandlerException : when at least one handler is missing
      * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
      */
-    public void reconfigure(Dictionary conf) throws UnacceptableConfiguration {
+    public void reconfigure(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
         m_delegate.reconfigure(conf);
     }
 
+    /**
+     * Add a factory listener.
+     * @param l : the listener to add.
+     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void addFactoryStateListener(FactoryStateListener l) {
+        m_delegate.addFactoryStateListener(l);
+
+    }
+
+    public List getMissingHandlers() {
+        return m_delegate.getMissingHandlers();
+    }
+
+    public List getRequiredHandlers() {
+        return m_delegate.getRequiredHandlers();
+    }
+
+    /**
+     * Remove a service listener.
+     * @param l : the listener to remove
+     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void removeFactoryStateListener(FactoryStateListener l) {
+        m_delegate.removeFactoryStateListener(l);
+
+    }
+
+    public ComponentDescription getComponentDescription() {
+        return m_delegate.getComponentDescription();
+    }
+
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
index b7670e2..1ebbcf3 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
@@ -34,6 +34,11 @@
      * Service Registration attached to the service reference.
      */
     private ServiceRegistrationImpl m_registration = null;
+    
+    /**
+     * Component Instance.
+     */
+    private ComponentInstance m_cm;
 
     /**
      * Constructor.
@@ -43,6 +48,7 @@
      */
     public ServiceReferenceImpl(ComponentInstance cm, ServiceRegistrationImpl sr) {
         m_registration = sr;
+        m_cm = cm;
     }
 
     /**
@@ -51,7 +57,7 @@
      * @see org.osgi.framework.ServiceReference#getBundle()
      */
     public Bundle getBundle() {
-        throw new UnsupportedOperationException("getUsingBundles is not supported in scope");
+        return m_cm.getContext().getBundle();
     }
 
     /**
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
index bbaddc5..6818899 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
@@ -78,7 +78,7 @@
     /**
      * Property Keys List.
      */
-    private transient List m_list = new ArrayList();
+    private List m_list = new ArrayList();
 
     /**
      * Constructor.
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
index dc1b75c..c14c5e4 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
@@ -104,11 +104,11 @@
     public boolean ungetService(ComponentInstance cm, ServiceReference ref) {
 
         ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
-        if (!reg.isValid()) {
-            return false;
-        } else {
+        if (reg.isValid()) {
             reg.ungetService(cm, reg.getService());
             return true;
+        } else {
+            return false;
         }
     }
 
@@ -159,11 +159,10 @@
 
     /**
      * Dispatch a service event.
-     * 
      * @param event : the service to dispatch
      */
     private void fireServiceChanged(ServiceEvent event) {
-        synchronized (this) {
+        synchronized (m_listeners) {
             // Iterate on the service listener list to notify service listener
             for (int i = 0; i < m_listeners.size(); i++) {
                 ListenerInfo li = (ListenerInfo) m_listeners.get(i);
@@ -184,10 +183,11 @@
      * @param className : required interface
      * @param expr : LDAP filter
      * @return : the list of available service references.
-     * @throws InvalidSyntaxException occurs when the LDAP filter is malformed.
+     * @throws InvalidSyntaxException
+     *             occurs when the LDAP filter is malformed.
      */
     public ServiceReference[] getServiceReferences(String className, String expr) throws InvalidSyntaxException {
-        synchronized (this) {
+        synchronized (m_regs) {
             // Define filter if expression is not null.
             Filter filter = null;
             if (expr != null) {
@@ -238,7 +238,7 @@
      * @return the first available provider or null if none available.
      */
     public ServiceReference getServiceReference(String clazz) {
-        synchronized (this) {
+        synchronized (m_regs) {
             try {
                 ServiceReference[] refs = getServiceReferences(clazz, null);
                 if (refs != null) {
@@ -253,13 +253,12 @@
 
     /**
      * Get a service object.
-     * 
      * @param cm : component instance requiring the service.
      * @param ref : the required reference.
      * @return the service object.
      */
     public Object getService(ComponentInstance cm, ServiceReference ref) {
-        synchronized (this) {
+        synchronized (m_regs) {
             // Look for the service registration for this ref
             ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
             if (reg.isValid()) {
@@ -274,14 +273,13 @@
     /**
      * Get all service references consistent with the given interface and
      * filter.
-     * 
      * @param clazz : the required interface.
      * @param filter : the LDAP filter.
      * @return the list of all service reference or null if none available.
      * @throws InvalidSyntaxException occurs when the LDAP filter is malformed.
      */
     public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        synchronized (this) {
+        synchronized (m_regs) {
             // Can delegate on getServiceReference, indeed their is no test on
             // the "modularity" conflict.
             return getServiceReferences(clazz, filter);
@@ -290,26 +288,28 @@
 
     /**
      * Add a service listener with a filter.
-     * 
      * @param listener : the service listener to add
      * @param filter : LDAP filter
      */
     public void addServiceListener(ServiceListener listener, String filter) {
-        synchronized (this) {
-            ListenerInfo li = new ListenerInfo();
-            li.m_listener = listener;
-            try {
-                li.m_filter = m_bc.createFilter(filter);
-            } catch (InvalidSyntaxException ex) {
-                System.err.println("Scope Service Registry : Problem when creating a service listener " + ex.getMessage());
-            }
-            m_listeners.add(li);
+        // If the filter is null, subscribe with no filter.
+        if (filter == null) {
+            addServiceListener(listener);
+            return;
         }
+        
+        ListenerInfo li = new ListenerInfo();
+        li.m_listener = listener;
+        try {
+            li.m_filter = m_bc.createFilter(filter);
+        } catch (InvalidSyntaxException ex) {
+            System.err.println("Scope Service Registry : Problem when creating a service listener " + ex.getMessage());
+        }
+        m_listeners.add(li);
     }
 
     /**
      * Dispatch a service properties modified event.
-     * 
      * @param reg : the implicated service registration.
      */
     public void servicePropertiesModified(ServiceRegistrationImpl reg) {
@@ -318,14 +318,11 @@
 
     /**
      * Unregister a service.
-     * 
      * @param reg : the service registration to unregister
      */
     public void unregisterService(ServiceRegistrationImpl reg) {
-        synchronized (this) {
-            m_regs.remove(reg);
-            fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
-        }
+        m_regs.remove(reg);
+        fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
     }
 
     /**
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
index 0905d69..bd057aa 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
@@ -138,14 +138,5 @@
         public void setCaseSensitive(boolean b) {
             m_isCaseSensitive = b;
         }
-
-        /**
-         * Does not support cloning.
-         * @return The current map
-         * @see java.lang.Object#clone()
-         */
-        public Object clone() {
-            return this;
-        }
     }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
index abc1053..ff9ab36 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
@@ -19,16 +19,12 @@
 package org.apache.felix.ipojo.composite.architecture;
 
 import java.util.Dictionary;
-import java.util.Properties;
 
 import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.CompositeManager;
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.metadata.Element;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
+import org.apache.felix.ipojo.util.Logger;
 
 /**
  * Composite Architecture Handler.
@@ -38,17 +34,6 @@
 public class ArchitectureHandler extends CompositeHandler implements Architecture {
 
     /**
-     * Composite Manager.
-     */
-    private CompositeManager m_manager;
-
-    /**
-     * Service Registration of the Architecture service provided by this
-     * handler.
-     */
-    private ServiceRegistration m_sr;
-
-    /**
      * Name of the component.
      */
     private String m_name;
@@ -56,55 +41,27 @@
     /**
      * Configure the handler.
      * 
-     * @param im : the instance manager
      * @param metadata : the metadata of the component
      * @param configuration : the instance configuration
      * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
      * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(CompositeManager im, Element metadata, Dictionary configuration) {
-        if (metadata.containsAttribute("architecture")) {
-            String isArchitectureEnabled = (metadata.getAttribute("architecture")).toLowerCase();
-            if (isArchitectureEnabled.equalsIgnoreCase("true")) {
-                im.register(this);
-            }
-        }
-
+    public void configure(Element metadata, Dictionary configuration) {
         m_name = (String) configuration.get("name");
-
-        m_manager = im;
     }
 
     /**
      * Stop the handler.
-     * Unregister the service.
      * @see org.apache.felix.ipojo.Handler#stop()
      */
-    public void stop() {
-        if (m_sr != null) {
-            m_sr.unregister();
-            m_sr = null;
-        }
-    }
+    public void stop() { }
 
     /**
      * Start the handler.
-     * Register the service.
      * @see org.apache.felix.ipojo.Handler#start()
      */
-    public void start() {
-        // Unregister the service if already registered
-        if (m_sr != null) {
-            m_sr.unregister();
-        }
-
-        // Register the ManagedService
-        BundleContext bc = m_manager.getContext();
-        Dictionary properties = new Properties();
-        properties.put("Component.Type", m_manager.getComponentDescription().getName());
-        properties.put(Constants.SERVICE_PID, m_name);
-
-        m_sr = bc.registerService(Architecture.class.getName(), this, properties);
+    public void start() { 
+        log(Logger.INFO, "Start composite architecture handler with " + m_name + " name");
     }
 
     /**
@@ -113,7 +70,7 @@
      * @see org.apache.felix.ipojo.architecture.Architecture#getDescription()
      */
     public InstanceDescription getInstanceDescription() {
-        return m_manager.getInstanceDescription();
+        return getCompositeManager().getInstanceDescription();
     }
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
index 07b01a0..df22f6f 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
@@ -25,21 +25,17 @@
 
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.InstanceStateListener;
+import org.apache.felix.ipojo.MissingHandlerException;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.UnacceptableConfiguration;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
 
 /**
  * Composite Instance Handler.
@@ -47,38 +43,30 @@
  * This instance is determine by its type and a configuration.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceHandler extends CompositeHandler implements ServiceListener, InstanceStateListener {
+public class InstanceHandler extends CompositeHandler implements InstanceStateListener {
 
     /**
-     * Bundle context.
-     */
-    private BundleContext m_context;
-    
-    /**
      * Internal context.
      */
     private ServiceContext m_scope;
+
+    /**
+     * Is the handler valid ?
+     * (Lifecycle controller)
+     */
+    private boolean m_isValid = false;
     
     /**
-     * Instance logger.
+     * Available factories.
      */
-    private Logger m_logger;
+    private Factory[] m_factories;
     
-    /**
-     * Composite Manager.
-     */
-    private CompositeManager m_manager;
-    
-    /**
-     * IS the handler valid ?
-     */
-    private boolean m_validity = false;
-    
+
     /**
      * This structure aims to manage a configuration. It stores all necessary
      * information to create an instance and to track the factory.
      */
-    private class ManagedConfiguration {
+    class ManagedConfiguration {
         /**
          * Configuration of the instance to create.
          */
@@ -93,6 +81,11 @@
          * Created instance.
          */
         private ComponentInstance m_instance;
+        
+        /**
+         * Desired Factory (can be the classname).
+         */
+        private String m_desiredFactory;
 
         /**
          * Constructor.
@@ -101,6 +94,7 @@
          */
         ManagedConfiguration(Dictionary conf) {
             m_configuration = conf;
+            m_desiredFactory = (String) conf.get("component");
         }
 
         /**
@@ -118,6 +112,10 @@
         String getFactory() {
             return m_factoryName;
         }
+        
+        String getNeededFactoryName() {
+            return m_desiredFactory;
+        }
 
         /**
          * Return the created instance.
@@ -164,49 +162,48 @@
             config.setFactory(fact.getName());
             config.getInstance().addInstanceStateListener(this);
         } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
+            log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
+        } catch (MissingHandlerException e) {
+            log(Logger.ERROR, "The instance creation has failed, at least one handler is missing", e);
+        } catch (ConfigurationException e) {
+            log(Logger.ERROR, "The instance creation has failed, an error during the configuration has occured", e);
         }
     }
-
+    
     /**
-     * Service Listener implementation.
-     * @param ev : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+     * A new valid factory appears.
+     * @param f : factory.
      */
-    public void serviceChanged(ServiceEvent ev) {
-        ServiceReference ref = ev.getServiceReference();
-        String factoryName = (String) ref.getProperty(org.osgi.framework.Constants.SERVICE_PID);
-        String componentClass = (String) ref.getProperty("component.class");
+    public void bindFactory(Factory f) {
         boolean implicated = false;
-        if (ev.getType() == ServiceEvent.REGISTERED) {
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() == null
-                        && (m_configurations[i].getConfiguration().get("component").equals(factoryName)
-                        || m_configurations[i].getConfiguration().get("component").equals(componentClass))) {
-                    Factory fact = (Factory) m_context.getService(ref);
-                    createInstance(fact, m_configurations[i]);
-                    implicated = true;
-                }
+        String factName = f.getName();
+        String className = f.getComponentDescription().getClassName();
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {
+                createInstance(f, m_configurations[i]);
+                implicated = true;
             }
-            if (implicated && !m_validity && checkValidity()) {
-                m_manager.checkInstanceState();
-            }
-            return;
         }
-
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factoryName)) {
-                    m_configurations[i].setInstance(null);
-                    m_configurations[i].setFactory(null);
-                    m_context.ungetService(ref);
-                    implicated = true;
-                }
+        if (implicated && ! m_isValid) {
+            checkValidity();
+        }
+    }
+    
+    /**
+     * An existing factory disappears or becomes invalid.
+     * @param f : factory
+     */
+    public void unbindFactory(Factory f) {
+        boolean implicated = false;
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(f.getName())) {
+                m_configurations[i].setInstance(null);
+                m_configurations[i].setFactory(null);
+                implicated = true;
             }
-            if (implicated && m_validity && !checkValidity()) {
-                m_manager.checkInstanceState();
-            }
-            return;
+        }
+        if (implicated && m_isValid) {
+            checkValidity();
         }
     }
 
@@ -214,31 +211,28 @@
      * Stop all created instances.
      */
     public synchronized void stop() {
-        m_context.removeServiceListener(this);
         for (int i = 0; i < m_configurations.length; i++) {
             if (m_configurations[i].getInstance() != null) {
                 m_configurations[i].getInstance().removeInstanceStateListener(this);
-                m_configurations[i].getInstance().dispose();
+                if (m_configurations[i].getInstance().getState() != ComponentInstance.DISPOSED) {
+                    m_configurations[i].getInstance().dispose();
+                }
             }
             m_configurations[i].setInstance(null);
             m_configurations[i].setFactory(null);
         }
-        m_configurations = null;
+        m_configurations = new ManagedConfiguration[0];
     }
-    
-    
+
     /**
      * Configure method.
-     * @param im : instance manager.
      * @param metadata : component type metadata.
      * @param configuration : instance configuration.
+     * @throws ConfigurationException : occurs an instance cannot be parsed correctly. 
      * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(CompositeManager im, Element metadata, Dictionary configuration) {
-        m_manager = im;
-        m_context = im.getContext();
-        m_logger = im.getFactory().getLogger();
-        m_scope = im.getServiceContext();
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        m_scope = getCompositeManager().getServiceContext();
         Element[] instances = metadata.getElements("instance");
         m_configurations = new ManagedConfiguration[instances.length];
         for (int i = 0; i < instances.length; i++) {
@@ -246,20 +240,15 @@
             try {
                 conf = parseInstance(instances[i]);
             } catch (ParseException e) {
-                m_logger.log(Logger.ERROR, "An instance cannot be parsed correctly", e);
-                return;
+                log(Logger.ERROR, "An instance cannot be parsed correctly", e);
+                throw new ConfigurationException("An instance cannot be parsed correctly : " + e.getMessage(), getCompositeManager().getFactory().getName());
             }
             m_configurations[i] = new ManagedConfiguration(conf);
         }
-
-        if (m_configurations.length > 0) {
-            im.register(this);
-        }
     }
-    
+
     /**
      * Parse an Element to get a dictionary.
-     * 
      * @param instance : the Element describing an instance.
      * @return : the resulting dictionary
      * @throws ParseException : occurs when a configuration cannot be parse correctly.
@@ -269,10 +258,8 @@
         if (instance.containsAttribute("name")) {
             dict.put("name", instance.getAttribute("name"));
         }
-        if (!instance.containsAttribute("component")) {
-            throw new ParseException("An instance does not have the 'component' attribute");
-        }
-        
+        if (!instance.containsAttribute("component")) { throw new ParseException("An instance does not have the 'component' attribute"); }
+
         dict.put("component", instance.getAttribute("component"));
 
         for (int i = 0; i < instance.getElements("property").length; i++) {
@@ -281,7 +268,7 @@
 
         return dict;
     }
-    
+
     /**
      * Parse a property.
      * @param prop : the current element to parse
@@ -290,9 +277,7 @@
      */
     private void parseProperty(Element prop, Dictionary dict) throws ParseException {
         // Check that the property has a name
-        if (!prop.containsAttribute("name")) {
-            throw new ParseException("A property does not have the 'name' attribute");
-        }
+        if (!prop.containsAttribute("name")) { throw new ParseException("A property does not have the 'name' attribute"); }
         // Final case : the property element has a 'value' attribute
         if (prop.containsAttribute("value")) {
             dict.put(prop.getAttribute("name"), prop.getAttribute("value"));
@@ -300,9 +285,7 @@
             // Recursive case
             // Check if there is 'property' element
             Element[] subProps = prop.getElements("property");
-            if (subProps.length == 0) {
-                throw new ParseException("A complex property must have at least one 'property' sub-element");
-            }
+            if (subProps.length == 0) { throw new ParseException("A complex property must have at least one 'property' sub-element"); }
             Dictionary dict2 = new Properties();
             for (int i = 0; i < subProps.length; i++) {
                 parseProperty(subProps[i], dict2);
@@ -315,45 +298,20 @@
      * Start method.
      * @see org.apache.felix.ipojo.CompositeHandler#start()
      */
-    public void start() {
-        for (int i = 0; i < m_configurations.length; i++) {
-
-            // Get the component type name :
-            String componentType = (String) m_configurations[i].getConfiguration().get("component");
-            Factory fact = null;
-
-            try {
-                String fil = "(|(" + org.osgi.framework.Constants.SERVICE_PID + "=" + componentType + ")(component.class=" + componentType + "))";
-                ServiceReference[] refs = m_context.getServiceReferences(org.apache.felix.ipojo.Factory.class.getName(), fil);
-                if (refs != null) {
-                    fact = (Factory) m_context.getService(refs[0]);
-                    createInstance(fact, m_configurations[i]);
+    public void start() { 
+        for (int j = 0; j < m_factories.length; j++) {
+            String factName = m_factories[j].getName();
+            String className = m_factories[j].getComponentDescription().getClassName(); 
+            for (int i = 0; i < m_configurations.length; i++) {
+                if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {
+                    createInstance(m_factories[j], m_configurations[i]);
                 }
-            } catch (InvalidSyntaxException e) {
-                m_logger.log(Logger.ERROR, "Invalid syntax filter for the type : " + componentType, e);
             }
         }
-
-        // Register a service listener on Factory Service
-        try {
-            m_context.addServiceListener(this, "(objectClass=" + Factory.class.getName() + ")");
-        } catch (InvalidSyntaxException e) {
-            m_logger.log(Logger.ERROR, "Invalid syntax filter when registering a listener on Factory Service", e);
-        }
         
-        //Compute validity 
         checkValidity();
     }
-    
-    /**
-     * The handler is valid if all managed instances are created and are valid.
-     * @return true if all managed configuration have been instanciated and are valid.
-     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
-     */
-    public boolean isValid() {
-        return m_validity;
-    }
-    
+
     /**
      * Check handler validity.
      * The method update the m_validity field.
@@ -362,56 +320,57 @@
     private boolean checkValidity() {
         for (int i = 0; i < m_configurations.length; i++) {
             if (m_configurations[i].getInstance() == null || m_configurations[i].getInstance().getState() != ComponentInstance.VALID) {
-                m_validity = false;
+                m_isValid = false;
                 return false;
             }
         }
-        m_validity = true;
+        m_isValid = true;
         return true;
     }
 
-    /** Instance state listener.
+    /**
+     *  Instance state listener.
      *  This method listens when managed instance states change.
      *  @param instance : instance
      *  @param newState : the now state of the given instance
      *  @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
      */
     public void stateChanged(ComponentInstance instance, int newState) {
-        switch(newState) {
-            case ComponentInstance.DISPOSED : 
-            case ComponentInstance.STOPPED :
+        switch (newState) {
+            case ComponentInstance.DISPOSED:
+            case ComponentInstance.STOPPED:
                 break; // Should not happen
-            case ComponentInstance.VALID :
-                if (! m_validity && checkValidity()) { 
-                    m_manager.checkInstanceState();
+            case ComponentInstance.VALID:
+                if (!m_isValid) {
+                    checkValidity();
                 }
                 break;
-            case ComponentInstance.INVALID :
-                if (m_validity && ! checkValidity()) {
-                    m_manager.checkInstanceState();
+            case ComponentInstance.INVALID:
+                if (m_isValid) {
+                    checkValidity();
                 }
                 break;
-            default :
+            default:
                 break;
-            
+
         }
     }
-    
+
     /**
      * Method returning an instance object of the given component type.
      * This method must be called only on 'primitive' type.
      * @param type : type.
      * @return an instance object or null if not found.
      */
-    public Object getObjectFromInstance(String type)  {
+    public Object getObjectFromInstance(String type) {
         for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null && type.equals(m_configurations[i].getFactory()) && m_configurations[i].getInstance().getState() == ComponentInstance.VALID) {
-                return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject();
+            if (m_configurations[i].getInstance() != null && type.equals(m_configurations[i].getFactory()) && m_configurations[i].getInstance().getState() == ComponentInstance.VALID) { 
+                return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject(); 
             }
         }
         return null;
     }
-    
+
     /**
      * Return the handler description, i.e. the state of created instances.
      * @return the handler description.
@@ -420,13 +379,11 @@
     public HandlerDescription getDescription() {
         List l = new ArrayList();
         for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null) {
-                l.add(m_configurations[i]);
-            }
+            l.add(m_configurations[i]);
         }
-        return new InstanceHandlerDescription(InstanceHandler.class.getName(), m_validity, l);
+        return new InstanceHandlerDescription(this, l);
     }
-    
+
     /**
      * Get the list of used component type.
      * @return the list containing the used component type
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
index 707ed4c..844e3e6 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
@@ -21,7 +21,9 @@
 import java.util.List;
 
 import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.CompositeHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler.ManagedConfiguration;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 
@@ -40,12 +42,11 @@
     /**
      * Constructor.
      * 
-     * @param arg0 : name of the handler
-     * @param arg1 : validity of the handler
+     * @param h : handler
      * @param insts : list of component instances
      */
-    public InstanceHandlerDescription(String arg0, boolean arg1, List insts) {
-        super(arg0, arg1);
+    public InstanceHandlerDescription(CompositeHandler h, List insts) {
+        super(h);
         m_instances = insts;
     }
 
@@ -57,25 +58,31 @@
     public Element getHandlerInfo() {
         Element instances = super.getHandlerInfo();
         for (int i = 0; i < m_instances.size(); i++) {
-            ComponentInstance inst = (ComponentInstance) m_instances.get(i);
+            ManagedConfiguration inst = (ManagedConfiguration) m_instances.get(i);
             Element instance = new Element("Instance", "");
-            instance.addAttribute(new Attribute("Name", inst.getInstanceName()));
-            String state = null;
-            switch(inst.getState()) {
-                case ComponentInstance.DISPOSED : 
-                    state = "disposed"; break;
-                case ComponentInstance.STOPPED : 
-                    state = "stopped"; break;
-                case ComponentInstance.VALID : 
-                    state = "valid"; break;
-                case ComponentInstance.INVALID : 
-                    state = "invalid"; break;
-                default :
-                    break;
+            if (inst.getInstance() != null) {
+                instance.addAttribute(new Attribute("Factory", inst.getFactory()));
+                instance.addAttribute(new Attribute("Name", inst.getInstance().getInstanceName()));
+                String state = null;
+                switch(inst.getInstance().getState()) {
+                    case ComponentInstance.DISPOSED : 
+                        state = "disposed"; break;
+                    case ComponentInstance.STOPPED : 
+                        state = "stopped"; break;
+                    case ComponentInstance.VALID : 
+                        state = "valid"; break;
+                    case ComponentInstance.INVALID : 
+                        state = "invalid"; break;
+                    default :
+                        break;
+                }
+                instance.addAttribute(new Attribute("State", state));
+                instance.addElement(inst.getInstance().getInstanceDescription().getDescription());
+            } else {
+                instance.addAttribute(new Attribute("Factory", inst.getConfiguration().get("component").toString()));
+                instance.addAttribute(new Attribute("State", "Not Available"));
             }
-            instance.addAttribute(new Attribute("State", state));
-            instance.addElement(inst.getInstanceDescription().getDescription());
-            instances.addElement(instances);
+            instances.addElement(instance);
         }
         return instances;
     }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
similarity index 61%
copy from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
copy to ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
index 77de77b..9994698 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
@@ -20,6 +20,7 @@
 
 import java.util.List;
 
+import org.apache.felix.ipojo.CompositeHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
@@ -28,12 +29,7 @@
  * Description of the Import Export Handler.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ImportExportDescription extends HandlerDescription {
-
-    /**
-     * List of imports.
-     */
-    private List m_imports;
+public class ExportDescription extends HandlerDescription {
 
     /**
      * List of exports.
@@ -43,14 +39,11 @@
     /**
      * Constructor.
      * 
-     * @param name : name of the handler
-     * @param isValid : handler validity
-     * @param importers : list of managed imports
+     * @param h : composite handler
      * @param exporters : list of managed exports
      */
-    public ImportExportDescription(String name, boolean isValid, List importers, List exporters) {
-        super(name, isValid);
-        m_imports = importers;
+    public ExportDescription(CompositeHandler h, List exporters) {
+        super(h);
         m_exports = exporters;
     }
 
@@ -61,26 +54,9 @@
      */
     public Element getHandlerInfo() {
         Element handler = super.getHandlerInfo();
-        for (int i = 0; i < m_imports.size(); i++) {
-            ServiceImporter imp = (ServiceImporter) m_imports.get(i);
-            Element impo = new Element("Requires", "");
-            impo.addAttribute(new Attribute("Specification", imp.getSpecification()));
-            if (imp.getFilter() != null) { impo.addAttribute(new Attribute("Filter", imp.getFilter())); }
-            if (imp.isSatisfied()) {
-                impo.addAttribute(new Attribute("State", "resolved"));
-                for (int j = 0; j < imp.getProviders().size(); j++) {
-                    Element pr = new Element("Provider", "");
-                    pr.addAttribute(new Attribute("name", (String) imp.getProviders().get(j)));
-                    impo.addElement(pr);
-                }
-            } else {
-                impo.addAttribute(new Attribute("State", "unresolved"));
-            }
-            handler.addElement(impo);
-        }
         for (int i = 0; i < m_exports.size(); i++) {
             ServiceExporter exp = (ServiceExporter) m_exports.get(i);
-            Element expo = new Element("Export", "");
+            Element expo = new Element("Exports", "");
             expo.addAttribute(new Attribute("Specification", exp.getSpecification()));
             expo.addAttribute(new Attribute("Filter", exp.getFilter()));
             if (exp.isSatisfied()) {
@@ -93,5 +69,4 @@
         return handler;
 
     }
-
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java
new file mode 100644
index 0000000..186b984
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java
@@ -0,0 +1,204 @@
+/* 

+ * 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.composite.service.importer;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+

+import org.apache.felix.ipojo.CompositeHandler;

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.architecture.ComponentDescription;

+import org.apache.felix.ipojo.architecture.HandlerDescription;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.util.Logger;

+import org.osgi.framework.BundleContext;

+

+/**

+ * This handler manages the import and the export of services from /

+ * to the parent context.

+ * 

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class ExportHandler extends CompositeHandler {

+

+    /**

+     * Service Scope.

+     */

+    private ServiceContext m_scope;

+

+    /**

+     * Parent context.

+     */

+    private BundleContext m_context;

+

+    /**

+     * List of exporters.

+     */

+    private List m_exporters = new ArrayList();

+

+    /**

+     * Is the handler valid ?

+     * (Lifecycle controller)

+     */

+    private boolean m_valid;

+

+    /**

+     * Initialize the component type.

+     * @param cd : component type description to populate.

+     * @param metadata : component type metadata.

+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)

+     */

+    public void initializeComponentFactory(ComponentDescription cd, Element metadata) {

+        // Update the component type description

+        Element[] exp = metadata.getElements("exports");

+        for (int i = 0; i < exp.length; i++) {

+            if (exp[i].containsAttribute("specification")) { // Malformed exports

+                String specification = exp[i].getAttribute("specification");

+                cd.addProvidedServiceSpecification(specification);

+            }

+        }

+    }

+

+    /**

+     * Configure the handler.

+     * @param metadata : the metadata of the component

+     * @param conf : the instance configuration

+     * @throws ConfigurationException : if the specification attribute is missing in the metadata.

+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,

+     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

+     */

+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {

+        m_context = getCompositeManager().getContext();

+        m_scope = getCompositeManager().getServiceContext();

+

+        Element[] exp = metadata.getElements("exports");

+

+        for (int i = 0; i < exp.length; i++) {

+            boolean optional = false;

+            boolean aggregate = false;

+            String specification = null;

+

+            if (exp[i].containsAttribute("specification")) {

+                specification = exp[i].getAttribute("specification");

+                String filter = "(objectClass=" + specification + ")";

+                if (exp[i].containsAttribute("optional") && exp[i].getAttribute("optional").equalsIgnoreCase("true")) {

+                    optional = true;

+                }

+                if (exp[i].containsAttribute("aggregate") && exp[i].getAttribute("aggregate").equalsIgnoreCase("true")) {

+                    aggregate = true;

+                }

+                if (exp[i].containsAttribute("filter")) {

+                    String classnamefilter = "(objectClass=" + specification + ")";

+                    filter = null;

+                    if ("".equals(exp[i].getAttribute("filter"))) {

+                        filter = classnamefilter;

+                    } else {

+                        filter = "(&" + classnamefilter + exp[i].getAttribute("filter") + ")";

+                    }

+                }

+                ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, m_scope, m_context, this);

+                m_exporters.add(si);

+            } else { // Malformed exports

+                log(Logger.ERROR, "Malformed exports : the specification attribute is mandatory");

+                throw new ConfigurationException("Malformed exports : the specification attribute is mandatory", getCompositeManager().getFactory().getName());

+            }

+        }

+    }

+

+    /**

+     * Start the handler.

+     * Start importers and exporters.

+     * @see org.apache.felix.ipojo.CompositeHandler#start()

+     */

+    public void start() {

+        for (int i = 0; i < m_exporters.size(); i++) {

+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);

+            se.start();

+        }

+

+        isHandlerValid();

+

+    }

+

+    /**

+     * Stop the handler.

+     * Stop all importers and exporters.

+     * @see org.apache.felix.ipojo.CompositeHandler#stop()

+     */

+    public void stop() {

+        for (int i = 0; i < m_exporters.size(); i++) {

+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);

+            se.stop();

+        }

+    }

+

+    /**

+     * Check the handler validity.

+     * @return true if all importers and exporters are valid

+     * @see org.apache.felix.ipojo.CompositeHandler#isValid()

+     */

+    private boolean isHandlerValid() {

+        for (int i = 0; i < m_exporters.size(); i++) {

+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);

+            if (!se.isSatisfied()) {

+                m_valid = false;

+                return false;

+            }

+        }

+

+        m_valid = true;

+        return true;

+    }

+

+    /**

+     * Notify the handler that an exporter becomes invalid.

+     * 

+     * @param exporter : the implicated exporter.

+     */

+    protected void invalidating(ServiceExporter exporter) {

+        // An export is no more valid

+        if (m_valid) {

+            m_valid = false;

+        }

+

+    }

+

+    /**

+     * Notify the handler that an exporter becomes valid.

+     * 

+     * @param exporter : the implicated exporter.

+     */

+    protected void validating(ServiceExporter exporter) {

+        // An import becomes valid

+        if (!m_valid) {

+            isHandlerValid();

+        }

+    }

+

+    /**

+     * Get the import / export handler description.

+     * @return the handler description

+     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()

+     */

+    public HandlerDescription getDescription() {

+        return new ExportDescription(this, m_exporters);

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
similarity index 69%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
index 77de77b..0a56014 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
@@ -1,97 +1,79 @@
-/* 
- * 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.composite.service.importer;
-
-import java.util.List;
-
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-
-/**
- * Description of the Import Export Handler.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ImportExportDescription extends HandlerDescription {
-
-    /**
-     * List of imports.
-     */
-    private List m_imports;
-
-    /**
-     * List of exports.
-     */
-    private List m_exports;
-
-    /**
-     * Constructor.
-     * 
-     * @param name : name of the handler
-     * @param isValid : handler validity
-     * @param importers : list of managed imports
-     * @param exporters : list of managed exports
-     */
-    public ImportExportDescription(String name, boolean isValid, List importers, List exporters) {
-        super(name, isValid);
-        m_imports = importers;
-        m_exports = exporters;
-    }
-
-    /**
-     * Build the ImportExport handler description.
-     * @return the handler description
-     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
-     */
-    public Element getHandlerInfo() {
-        Element handler = super.getHandlerInfo();
-        for (int i = 0; i < m_imports.size(); i++) {
-            ServiceImporter imp = (ServiceImporter) m_imports.get(i);
-            Element impo = new Element("Requires", "");
-            impo.addAttribute(new Attribute("Specification", imp.getSpecification()));
-            if (imp.getFilter() != null) { impo.addAttribute(new Attribute("Filter", imp.getFilter())); }
-            if (imp.isSatisfied()) {
-                impo.addAttribute(new Attribute("State", "resolved"));
-                for (int j = 0; j < imp.getProviders().size(); j++) {
-                    Element pr = new Element("Provider", "");
-                    pr.addAttribute(new Attribute("name", (String) imp.getProviders().get(j)));
-                    impo.addElement(pr);
-                }
-            } else {
-                impo.addAttribute(new Attribute("State", "unresolved"));
-            }
-            handler.addElement(impo);
-        }
-        for (int i = 0; i < m_exports.size(); i++) {
-            ServiceExporter exp = (ServiceExporter) m_exports.get(i);
-            Element expo = new Element("Export", "");
-            expo.addAttribute(new Attribute("Specification", exp.getSpecification()));
-            expo.addAttribute(new Attribute("Filter", exp.getFilter()));
-            if (exp.isSatisfied()) {
-                expo.addAttribute(new Attribute("State", "resolved"));
-            } else {
-                expo.addAttribute(new Attribute("State", "unresolved"));
-            }
-            handler.addElement(expo);
-        }
-        return handler;
-
-    }
-
-}
+/* 

+ * 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.composite.service.importer;

+

+import java.util.List;

+

+import org.apache.felix.ipojo.CompositeHandler;

+import org.apache.felix.ipojo.architecture.HandlerDescription;

+import org.apache.felix.ipojo.metadata.Attribute;

+import org.apache.felix.ipojo.metadata.Element;

+

+/**

+ * Description of the Import Export Handler.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class ImportDescription extends HandlerDescription {

+

+    /**

+     * List of exports.

+     */

+    private List m_imports;

+

+    /**

+     * Constructor.

+     * 

+     * @param h : composite handler

+     * @param importers : list of managed imports

+     */

+    public ImportDescription(CompositeHandler h, List importers) {

+        super(h);

+        m_imports = importers;

+    }

+

+    /**

+     * Build the ImportExport handler description.

+     * @return the handler description

+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()

+     */

+    public Element getHandlerInfo() {

+        Element handler = super.getHandlerInfo();

+        for (int i = 0; i < m_imports.size(); i++) {

+            ServiceImporter imp = (ServiceImporter) m_imports.get(i);

+            Element impo = new Element("Requires", "");

+            impo.addAttribute(new Attribute("Specification", imp.getSpecification()));

+            if (imp.getFilter() != null) {

+                impo.addAttribute(new Attribute("Filter", imp.getFilter()));

+            }

+            if (imp.isSatisfied()) {

+                impo.addAttribute(new Attribute("State", "resolved"));

+                for (int j = 0; j < imp.getProviders().size(); j++) {

+                    Element pr = new Element("Provider", "");

+                    pr.addAttribute(new Attribute("name", (String) imp.getProviders().get(j)));

+                    impo.addElement(pr);

+                }

+            } else {

+                impo.addAttribute(new Attribute("State", "unresolved"));

+            }

+            handler.addElement(impo);

+        }

+        return handler;

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
deleted file mode 100644
index 5d9100a..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
+++ /dev/null
@@ -1,312 +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.composite.service.importer;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.CompositeManager;
-import org.apache.felix.ipojo.PolicyServiceContext;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.BundleContext;
-
-/**
- * This handler manages the import and the export of services from /
- * to the parent context.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ImportExportHandler extends CompositeHandler {
-
-    /**
-     * Composite Manager.
-     */
-    private CompositeManager m_manager;
-
-    /**
-     * Service Scope.
-     */
-    private ServiceContext m_scope;
-
-    /**
-     * Parent context.
-     */
-    private BundleContext m_context;
-
-    /**
-     * List of importers.
-     */
-    private List m_importers = new ArrayList();
-
-    /**
-     * List of exporters.
-     */
-    private List m_exporters = new ArrayList();
-
-    /**
-     * Is the handler valid ?
-     */
-    private boolean m_valid;
-
-    /**
-     * Configure the handler.
-     * 
-     * @param im : the instance manager
-     * @param metadata : the metadata of the component
-     * @param conf : the instance configuration
-     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
-     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
-     */
-    public void configure(CompositeManager im, Element metadata, Dictionary conf) {
-        m_manager = im;
-        m_context = im.getContext();
-        m_scope = m_manager.getServiceContext();
-
-        Element[] imp = metadata.getElements("requires");
-
-        //DEPRECATED BLOCK:
-        if (imp.length == 0) {
-            imp = metadata.getElements("import");
-            if (imp.length != 0) {
-                im.getFactory().getLogger().log(Logger.WARNING, "Import is deprecated, please use 'requires' instead of 'import'");
-            }
-        }
-        // END OF DEPRECATED BLOCK
-        
-        Element[] exp = metadata.getElements("export");
-
-        for (int i = 0; i < imp.length; i++) {
-            boolean optional = false;
-            boolean aggregate = false;
-            String specification = null;
-
-            if (!imp[i].containsAttribute("specification")) { // Malformed import
-                im.getFactory().getLogger().log(Logger.ERROR, "Malformed import : the specification attribute is mandatory");
-            } else {
-                specification = imp[i].getAttribute("specification");
-                String filter = "(&(objectClass=" + specification + ")(!(service.pid=" + m_manager.getInstanceName() + ")))"; // Cannot import yourself
-                if (imp[i].containsAttribute("optional") && imp[i].getAttribute("optional").equalsIgnoreCase("true")) {
-                    optional = true;
-                }
-                if (imp[i].containsAttribute("aggregate") && imp[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
-                    aggregate = true;
-                }
-                if (imp[i].containsAttribute("filter")) {
-                    if (!imp[i].getAttribute("filter").equals("")) {
-                        filter = "(&" + filter + imp[i].getAttribute("filter") + ")";
-                    }
-                }
-                
-                String id = null;
-                if (imp[i].containsAttribute("id")) {
-                    id = imp[i].getAttribute("id");
-                }
-                
-                int scopePolicy = -1;
-                if (imp[i].containsAttribute("scope")) {
-                    if (imp[i].getAttribute("scope").equalsIgnoreCase("global")) {
-                        scopePolicy = PolicyServiceContext.GLOBAL;
-                    } else if (imp[i].getAttribute("scope").equalsIgnoreCase("composite")) {
-                        scopePolicy = PolicyServiceContext.LOCAL;
-                    } else if (imp[i].getAttribute("scope").equalsIgnoreCase("composite+global")) {
-                        scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
-                    }                
-                }
-                
-                ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, scopePolicy, id, this);
-                m_importers.add(si);
-            }
-        }
-
-        for (int i = 0; i < exp.length; i++) {
-            boolean optional = false;
-            boolean aggregate = false;
-            String specification = null;
-
-            if (!exp[i].containsAttribute("specification")) { // Malformed exports
-                im.getFactory().getLogger().log(Logger.ERROR, "Malformed exports : the specification attribute is mandatory");
-            } else {
-                specification = exp[i].getAttribute("specification");
-                String filter = "(objectClass=" + specification + ")";
-                if (exp[i].containsAttribute("optional") && exp[i].getAttribute("optional").equalsIgnoreCase("true")) {
-                    optional = true;
-                }
-                if (exp[i].containsAttribute("aggregate") && exp[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
-                    aggregate = true;
-                }
-                if (exp[i].containsAttribute("filter")) {
-                    String classnamefilter = "(objectClass=" + specification + ")";
-                    filter = "";
-                    if (!imp[i].getAttribute("filter").equals("")) {
-                        filter = "(&" + classnamefilter + exp[i].getAttribute("filter") + ")";
-                    } else {
-                        filter = classnamefilter;
-                    }
-                }
-                ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, m_scope, m_context, this);
-                // Update the component type description
-                m_manager.getComponentDescription().addProvidedServiceSpecification(specification);
-                m_exporters.add(si);
-            }
-        }
-
-        if (m_importers.size() > 0 || m_exporters.size() > 0) {
-            im.register(this);
-        }
-    }
-
-    /**
-     * Start the handler.
-     * Start importers and exporters.
-     * @see org.apache.felix.ipojo.CompositeHandler#start()
-     */
-    public void start() {
-        for (int i = 0; i < m_importers.size(); i++) {
-            ServiceImporter si = (ServiceImporter) m_importers.get(i);
-            si.start();
-        }
-
-        for (int i = 0; i < m_exporters.size(); i++) {
-            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
-            se.start();
-        }
-
-    }
-
-    /**
-     * Stop the handler.
-     * Stop all importers and exporters.
-     * @see org.apache.felix.ipojo.CompositeHandler#stop()
-     */
-    public void stop() {
-        for (int i = 0; i < m_importers.size(); i++) {
-            ServiceImporter si = (ServiceImporter) m_importers.get(i);
-            si.stop();
-        }
-
-        for (int i = 0; i < m_exporters.size(); i++) {
-            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
-            se.stop();
-        }
-    }
-
-    /**
-     * Check the handler validity.
-     * @return true if all importers and exporters are valid
-     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
-     */
-    public boolean isValid() {
-        for (int i = 0; i < m_importers.size(); i++) {
-            ServiceImporter si = (ServiceImporter) m_importers.get(i);
-            if (!si.isSatisfied()) {
-                m_valid = false;
-                return false;
-            }
-        }
-
-        for (int i = 0; i < m_exporters.size(); i++) {
-            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
-            if (!se.isSatisfied()) {
-                m_valid = false;
-                return false;
-            }
-        }
-
-        m_valid = true;
-        return true;
-    }
-
-    /**
-     * Notify the handler that an importer is no more valid.
-     * 
-     * @param importer : the implicated importer.
-     */
-    protected void invalidating(ServiceImporter importer) {
-        // An import is no more valid
-        if (m_valid) {
-            m_manager.checkInstanceState();
-        }
-
-    }
-
-    /**
-     * Notify the handler that an importer becomes valid.
-     * 
-     * @param importer : the implicated importer.
-     */
-    protected void validating(ServiceImporter importer) {
-        // An import becomes valid
-        if (!m_valid && isValid()) {
-            m_manager.checkInstanceState();
-        }
-
-    }
-
-    /**
-     * Notify the handler that an exporter becomes invalid.
-     * 
-     * @param exporter : the implicated exporter.
-     */
-    protected void invalidating(ServiceExporter exporter) {
-        // An import is no more valid
-        if (m_valid) {
-            m_manager.checkInstanceState();
-        }
-
-    }
-
-    /**
-     * Notify the handler that an exporter becomes valid.
-     * 
-     * @param exporter : the implicated exporter.
-     */
-    protected void validating(ServiceExporter exporter) {
-        // An import becomes valid
-        if (!m_valid && isValid()) {
-            m_manager.checkInstanceState();
-        }
-
-    }
-
-    /**
-     * Get the composite manager.
-     * @return the attached composite manager.
-     */
-    protected CompositeManager getManager() {
-        return m_manager;
-    }
-
-    /**
-     * Get the import / export handler description.
-     * @return the handler description
-     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
-     */
-    public HandlerDescription getDescription() {
-        return new ImportExportDescription(this.getClass().getName(), isValid(), m_importers, m_exporters);
-    }
-    
-    public List getRequirements() {
-        return m_importers;
-    }
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
new file mode 100644
index 0000000..04c5da1
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
@@ -0,0 +1,201 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This handler manages the import and the export of services from /
+ * to the parent context.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ImportHandler extends CompositeHandler {
+
+    /**
+     * Service Scope.
+     */
+    private ServiceContext m_scope;
+
+    /**
+     * Parent context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * List of importers.
+     */
+    private List m_importers = new ArrayList();
+
+    /**
+     * Is the handler valid ?
+     * (Lifecycle controller)
+     */
+    private boolean m_valid;
+    
+
+    /**
+     * Configure the handler.
+     * 
+     * @param metadata : the metadata of the component
+     * @param conf : the instance configuration
+     * @throws ConfigurationException : the specification attribute is missing. 
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
+     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
+        m_context = getCompositeManager().getContext();
+        m_scope = getCompositeManager().getServiceContext();
+
+        Element[] imp = metadata.getElements("requires");
+
+        for (int i = 0; i < imp.length; i++) {
+            boolean optional = false;
+            boolean aggregate = false;
+            String specification = null;
+
+            if (imp[i].containsAttribute("specification")) {
+                specification = imp[i].getAttribute("specification");
+                String filter = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
+                if (imp[i].containsAttribute("optional") && imp[i].getAttribute("optional").equalsIgnoreCase("true")) {
+                    optional = true;
+                }
+                if (imp[i].containsAttribute("aggregate") && imp[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
+                    aggregate = true;
+                }
+                if (imp[i].containsAttribute("filter")) {
+                    if (!"".equals(imp[i].getAttribute("filter"))) {
+                        filter = "(&" + filter + imp[i].getAttribute("filter") + ")";
+                    }
+                }
+                
+                String id = null;
+                if (imp[i].containsAttribute("id")) {
+                    id = imp[i].getAttribute("id");
+                }
+                
+                int scopePolicy = -1;
+                if (imp[i].containsAttribute("scope")) {
+                    if (imp[i].getAttribute("scope").equalsIgnoreCase("global")) {
+                        scopePolicy = PolicyServiceContext.GLOBAL;
+                    } else if (imp[i].getAttribute("scope").equalsIgnoreCase("composite")) {
+                        scopePolicy = PolicyServiceContext.LOCAL;
+                    } else if (imp[i].getAttribute("scope").equalsIgnoreCase("composite+global")) {
+                        scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
+                    }                
+                }
+                ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, scopePolicy, id, this);
+                m_importers.add(si);
+            } else { // Malformed import
+                log(Logger.ERROR, "Malformed imports : the specification attribute is mandatory");
+                throw new ConfigurationException("Malformed imports : the specification attribute is mandatory", getCompositeManager().getFactory().getName());
+            }
+        }
+    }
+
+    /**
+     * Start the handler.
+     * Start importers and exporters.
+     * @see org.apache.felix.ipojo.CompositeHandler#start()
+     */
+    public void start() {
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            si.start();
+        }
+        isHandlerValid();
+    }
+
+    /**
+     * Stop the handler.
+     * Stop all importers and exporters.
+     * @see org.apache.felix.ipojo.CompositeHandler#stop()
+     */
+    public void stop() {
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            si.stop();
+        }
+    }
+
+    /**
+     * Check the handler validity.
+     * @return true if all importers and exporters are valid
+     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+     */
+    public boolean isHandlerValid() {
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            if (!si.isSatisfied()) {
+                m_valid = false;
+                return false;
+            }
+        }
+        m_valid = true;
+        return true;
+    }
+
+    /**
+     * Notify the handler that an importer is no more valid.
+     * 
+     * @param importer : the implicated importer.
+     */
+    protected void invalidating(ServiceImporter importer) {
+        // An import is no more valid
+        if (m_valid) {
+            m_valid = false;
+        }
+    }
+
+    /**
+     * Notify the handler that an importer becomes valid.
+     * 
+     * @param importer : the implicated importer.
+     */
+    protected void validating(ServiceImporter importer) {
+        // An import becomes valid
+        if (!m_valid) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * Get the import / export handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return new ImportDescription(this, m_importers);
+    }
+    
+    public List getRequirements() {
+        return m_importers;
+    }
+}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
index e2dbc93..efb7fa1 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
@@ -24,12 +24,11 @@
 import java.util.Properties;
 
 import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 
@@ -38,7 +37,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceExporter implements ServiceListener {
+public class ServiceExporter implements TrackerCustomizer {
 
     /**
      * Destination context.
@@ -78,12 +77,17 @@
     /**
      * Reference of the handler.
      */
-    private ImportExportHandler m_handler;
+    private ExportHandler m_handler;
 
     /**
      * Is the exporter valid?
      */
     private boolean m_isValid;
+    
+    /**
+     * Tracker tracking internal service (to export).
+     */
+    private Tracker m_tracker;
 
     /**
      * Structure Reference, Registration, Service Object.
@@ -120,7 +124,7 @@
      * @param exp : handler
      */
     public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to,
-            ImportExportHandler exp) {
+            ExportHandler exp) {
         this.m_destination = to;
         this.m_origin = from;
         this.m_handler = exp;
@@ -140,49 +144,15 @@
      * Start the provider tracking and the publication.
      */
     public void start() {
-        try {
-            ServiceReference[] refs = m_origin.getServiceReferences(m_specification, null);
-            if (refs != null) {
-                for (int i = 0; i < refs.length; i++) {
-                    if (m_filter.match(refs[i])) {
-                        Record rec = new Record();
-                        rec.m_ref = refs[i];
-                        m_records.add(rec);
-                    }
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
-
-        // Publish available services
-        if (m_records.size() > 0) {
-            if (m_aggregate) {
-                for (int i = 0; i < m_records.size(); i++) {
-                    Record rec = (Record) m_records.get(i);
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            } else {
-                Record rec = (Record) m_records.get(0);
-                rec.m_svcObject = m_origin.getService(rec.m_ref);
-                rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-            }
-        }
-
-        // Register service listener
-        try {
-            m_origin.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
+        m_tracker = new Tracker(m_origin, m_filter, this);
+        m_tracker.open();
 
         m_isValid = isSatisfied();
     }
 
     /**
      * Transform service reference property in a dictionary.
-     * Service.PID and Factory.PID are injected too.
+     * instance.name and factory.name are injected too.
      * @param ref : the service reference.
      * @return the dictionary containing all property of the given service reference.
      */
@@ -193,8 +163,8 @@
             prop.put(keys[i], ref.getProperty(keys[i]));
         }
 
-        prop.put(Constants.SERVICE_PID, m_handler.getManager().getInstanceName());
-        prop.put("factory.pid", m_handler.getManager().getFactory().getName());
+        prop.put("instance.name", m_handler.getCompositeManager().getInstanceName());
+        prop.put("factory.name", m_handler.getCompositeManager().getFactory().getName());
 
         return prop;
     }
@@ -205,18 +175,20 @@
      * Unregister all exported services.
      */
     public void stop() {
-        m_origin.removeServiceListener(this);
+        m_tracker.close();
 
         for (int i = 0; i < m_records.size(); i++) {
             Record rec = (Record) m_records.get(i);
             rec.m_svcObject = null;
             if (rec.m_reg != null) {
                 rec.m_reg.unregister();
-                m_origin.ungetService(rec.m_ref);
+                rec.m_reg = null;
+                m_tracker.ungetService(rec.m_ref);
                 rec.m_ref = null;
             }
         }
 
+        m_tracker = null;
         m_records.clear();
 
     }
@@ -244,82 +216,71 @@
         }
         return l;
     }
-
-    /**
-     * Service Listener Implementation.
-     * @param ev : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent ev) {
-        if (ev.getType() == ServiceEvent.REGISTERED) {
-            arrivalManagement(ev.getServiceReference());
-        }
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
-            departureManagement(ev.getServiceReference());
-        }
-
-        if (ev.getType() == ServiceEvent.MODIFIED) {
-            if (m_filter.match(ev.getServiceReference())) {
-                // Test if the reference is always matching with the filter
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The reference is already contained => update the properties
-                    for (int i = 0; i < l.size(); i++) { // Stop the implied record
-                        Record rec = (Record) l.get(i);
-                        if (rec.m_reg != null) {
-                            rec.m_reg.setProperties(getProps(rec.m_ref));
-                        }
-                    }
-                } else { // it is a new matching service => add it
-                    arrivalManagement(ev.getServiceReference());
-                }
-            } else {
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The reference is already contained => the service does no more match
-                    departureManagement(ev.getServiceReference());
-                }
-            }
-        }
+    
+    protected String getSpecification() {
+        return m_specification;
+    }
+    
+    public String getFilter() {
+        return m_filterStr;
     }
 
     /**
-     * Manage the arrival of a service.
-     * @param ref : the new service reference.
+     * An exported service appears.
+     * @param reference : service reference
+     * @return true as the filter guaranty the export.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
      */
-    private void arrivalManagement(ServiceReference ref) {
-        // Check if the new service match
-        if (m_filter.match(ref)) {
-            // Add it to the record list
-            Record rec = new Record();
-            rec.m_ref = ref;
-            m_records.add(rec);
-            // Publishing ?
-            if (m_records.size() == 1 || m_aggregate) { // If the service is the
-                // first one, or if it
-                // is a multiple imports
-                rec.m_svcObject = m_origin.getService(rec.m_ref);
-                rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-            }
-            // Compute the new state
-            if (!m_isValid && isSatisfied()) {
-                m_isValid = true;
-                m_handler.validating(this);
-            }
+    public boolean addingService(ServiceReference reference) {
+        Record rec = new Record();
+        rec.m_ref = reference;
+        m_records.add(rec);
+        // Publishing ?
+        if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
+            rec.m_svcObject = m_tracker.getService(rec.m_ref);
+            rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
         }
+        // Compute the new state
+        if (!m_isValid && isSatisfied()) {
+            m_isValid = true;
+            m_handler.validating(this);
+        }
+        
+        return true;
     }
 
     /**
-     * Manage the departure of a service.
-     * @param ref : the new service reference.
+     * An exported service was modified.
+     * @param reference : modified reference
+     * @param service : service object
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
      */
-    private void departureManagement(ServiceReference ref) {
-        List l = getRecordsByRef(ref);
+    public void modifiedService(ServiceReference reference, Object service) { 
+        // A published service has been modified
+        List l = getRecordsByRef(reference);
+        for (int i = 0; i < l.size(); i++) { // Update the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_reg.setProperties(getProps(reference));
+            }
+        }
+    }
+    
+    /**
+     * An exported service disappears.
+     * @param reference : service reference
+     * @param service : service object
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        List l = getRecordsByRef(reference);
         for (int i = 0; i < l.size(); i++) { // Stop the implied record
             Record rec = (Record) l.get(i);
             if (rec.m_reg != null) {
                 rec.m_svcObject = null;
                 rec.m_reg.unregister();
                 rec.m_reg = null;
-                m_origin.ungetService(rec.m_ref);
+                m_tracker.ungetService(rec.m_ref);
             }
         }
         m_records.removeAll(l);
@@ -330,7 +291,7 @@
             if (!m_aggregate) { // Import the next one
                 Record rec = (Record) m_records.get(0);
                 if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
+                    rec.m_svcObject = m_tracker.getService(rec.m_ref);
                     rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
                 }
             }
@@ -340,14 +301,6 @@
                 m_handler.invalidating(this);
             }
         }
-    }
-
-    
-    protected String getSpecification() {
-        return m_specification;
-    }
-    
-    public String getFilter() {
-        return m_filterStr;
+        
     }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
index db73e9c..c16f0e4 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
@@ -25,12 +25,11 @@
 
 import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 
@@ -39,7 +38,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceImporter implements ServiceListener {
+public class ServiceImporter implements TrackerCustomizer {
 
     /**
      * Destination context.
@@ -85,11 +84,16 @@
      * Resolving policy.
      */
     private int m_policy;
+    
+    /**
+     * TRacker tracking imported service.
+     */
+    private Tracker m_tracker;
 
     /**
      * Reference on the handler.
      */
-    private ImportExportHandler m_handler;
+    private ImportHandler m_handler;
 
     private class Record {
         /**
@@ -104,6 +108,20 @@
          * Exposed Object.
          */
         private Object m_svcObject;
+        
+        /**
+         * Test object equality.
+         * @param o : object to confront against the current object.
+         * @return true if the two objects are equals (same service reference).
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        public boolean equals(Object o) {
+            if (o instanceof Record) {
+                Record rec = (Record) o;
+                return rec.m_ref == m_ref;
+            }
+            return false;
+        }
     }
 
     /**
@@ -135,7 +153,7 @@
      * @param in : handler
      */
     public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to, int policy, String id,
-            ImportExportHandler in) {
+            ImportHandler in) {
         this.m_destination = to;
         try {
             this.m_filter = from.createFilter(filter);
@@ -165,44 +183,9 @@
      * Start method to begin the import.
      */
     public void start() {
-        try {
-            m_origin = new PolicyServiceContext(m_handler.getManager().getGlobalContext(), m_handler.getManager().getParentServiceContext(), m_policy);
-            ServiceReference[] refs = m_origin.getServiceReferences(m_specification, null);
-            if (refs != null) {
-                for (int i = 0; i < refs.length; i++) {
-                    if (m_filter.match(refs[i])) {
-                        Record rec = new Record();
-                        rec.m_ref = refs[i];
-                        m_records.add(rec);
-                    }
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
-
-        // Publish available services
-        if (m_records.size() > 0) {
-            if (m_aggregate) {
-                for (int i = 0; i < m_records.size(); i++) {
-                    Record rec = (Record) m_records.get(i);
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            } else {
-                Record rec = (Record) m_records.get(0);
-                rec.m_svcObject = m_origin.getService(rec.m_ref);
-                rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-            }
-        }
-
-        // Register service listener
-        try {
-            m_origin.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
-
+        m_origin = new PolicyServiceContext(m_handler.getCompositeManager().getGlobalContext(), m_handler.getCompositeManager().getParentServiceContext(), m_policy);
+        m_tracker = new Tracker(m_origin, m_filter, this);
+        m_tracker.open();
         m_isValid = isSatisfied();
     }
 
@@ -226,18 +209,19 @@
      */
     public void stop() {
 
-        m_origin.removeServiceListener(this);
+        m_tracker.close();
 
         for (int i = 0; i < m_records.size(); i++) {
             Record rec = (Record) m_records.get(i);
             rec.m_svcObject = null;
             if (rec.m_reg != null) {
                 rec.m_reg.unregister();
-                m_origin.ungetService(rec.m_ref);
+                m_tracker.ungetService(rec.m_ref);
                 rec.m_ref = null;
             }
         }
-
+        
+        m_tracker = null;
         m_records.clear();
 
     }
@@ -267,102 +251,6 @@
         return l;
     }
 
-    /**
-     * Service Listener Implementation.
-     * @param ev : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent ev) {
-        if (ev.getType() == ServiceEvent.REGISTERED) {
-            arrivalManagement(ev.getServiceReference());
-        }
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
-            departureManagement(ev.getServiceReference());
-        }
-
-        if (ev.getType() == ServiceEvent.MODIFIED) {
-            if (m_filter.match(ev.getServiceReference())) {
-                // Test if the reference is always matching with the filter
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The reference is already contained => update the properties
-                    for (int i = 0; i < l.size(); i++) { // Stop the implied record
-                        Record rec = (Record) l.get(i);
-                        if (rec.m_reg != null) {
-                            rec.m_reg.setProperties(getProps(rec.m_ref));
-                        }
-                    }
-                } else { // it is a new matching service => add it
-                    arrivalManagement(ev.getServiceReference());
-                }
-            } else {
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The reference is already contained => the service does no more match
-                    departureManagement(ev.getServiceReference());
-                }
-            }
-        }
-    }
-
-    /**
-     * Manage the arrival of a consistent service.
-     * @param ref : the arrival service reference
-     */
-    private void arrivalManagement(ServiceReference ref) {
-        // Check if the new service match
-        if (m_filter.match(ref)) {
-            // Add it to the record list
-            Record rec = new Record();
-            rec.m_ref = ref;
-            m_records.add(rec);
-            // Publishing ?
-            if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
-                rec.m_svcObject = m_origin.getService(rec.m_ref);
-                rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-            }
-            // Compute the new state
-            if (!m_isValid && isSatisfied()) {
-                m_isValid = true;
-                m_handler.validating(this);
-            }
-        }
-    }
-
-    /**
-     * Manage the departure of a used reference.
-     * 
-     * @param ref : the leaving reference
-     */
-    private void departureManagement(ServiceReference ref) {
-        List l = getRecordsByRef(ref);
-        for (int i = 0; i < l.size(); i++) { // Stop the implied record
-            Record rec = (Record) l.get(i);
-            if (rec.m_reg != null) {
-                rec.m_svcObject = null;
-                rec.m_reg.unregister();
-                rec.m_reg = null;
-                m_origin.ungetService(rec.m_ref);
-            }
-        }
-        m_records.removeAll(l);
-
-        // Check the validity & if we need to re-import the service
-        if (m_records.size() > 0) {
-            // There is other available services
-            if (!m_aggregate) { // Import the next one
-                Record rec = (Record) m_records.get(0);
-                if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            }
-        } else {
-            if (!m_optional) {
-                m_isValid = false;
-                m_handler.invalidating(this);
-            }
-        }
-    }
-
     public String getSpecification() {
         return m_specification;
     }
@@ -374,7 +262,7 @@
     protected List getProviders() {
         List l = new ArrayList();
         for (int i = 0; i < m_records.size(); i++) {
-            l.add((((Record) m_records.get(i)).m_ref).getProperty(Constants.SERVICE_PID));
+            l.add((((Record) m_records.get(i)).m_ref).getProperty("instance.name"));
         }
         return l;
 
@@ -410,4 +298,85 @@
         return m_optional;
     }
 
+    /**
+     * A new service is detected.
+     * @param reference : service reference
+     * @return true if not already imported.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        // Else add it to the record list
+        Record rec = new Record();
+        rec.m_ref = reference;
+        if (m_records.contains(rec)) {
+            return false;
+        }
+        
+        m_records.add(rec);
+        // Publishing ?
+        if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
+            rec.m_svcObject = m_tracker.getService(rec.m_ref);
+            rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+        }
+        // Compute the new state
+        if (!m_isValid && isSatisfied()) {
+            m_isValid = true;
+            m_handler.validating(this);
+        }
+        return true;
+    }
+
+    /**
+     * An imported service was modified.
+     * @param reference : service reference
+     * @param service : service object (if already get)
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+        List l = getRecordsByRef(reference);
+        for (int i = 0; i < l.size(); i++) { // Stop the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_reg.setProperties(getProps(rec.m_ref));
+            }
+        }
+    }
+
+    /**
+     * An imported service disappears.
+     *@param reference : service reference
+     * @param service : service object (if already get)
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        List l = getRecordsByRef(reference);
+        for (int i = 0; i < l.size(); i++) { // Stop the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_svcObject = null;
+                rec.m_reg.unregister();
+                rec.m_reg = null;
+                m_tracker.ungetService(rec.m_ref);
+            }
+        }
+        m_records.removeAll(l);
+
+        // Check the validity & if we need to re-import the service
+        if (m_records.size() > 0) {
+            // There is other available services
+            if (!m_aggregate) { // Import the next one
+                Record rec = (Record) m_records.get(0);
+                if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
+                    rec.m_svcObject = m_tracker.getService(rec.m_ref);
+                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+                }
+            }
+        } else {
+            if (!m_optional) {
+                m_isValid = false;
+                m_handler.invalidating(this);
+            }
+        }
+    }
+
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
index c1a4094..c3275b9 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
@@ -24,6 +24,7 @@
 import java.util.Set;
 
 import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.CompositeHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
@@ -44,12 +45,11 @@
     /**
      * Constructor.
      * 
-     * @param arg0 : name of the handler
-     * @param arg1 : validity of the handler
+     * @param h : composite handler
      * @param insts : list of service instance
      */
-    public ServiceInstantiatorDescription(String arg0, boolean arg1, List insts) {
-        super(arg0, arg1);
+    public ServiceInstantiatorDescription(CompositeHandler h, List insts) {
+        super(h);
         m_instances = insts;
     }
 
@@ -77,7 +77,7 @@
                 Object o = map.get(ref);
                 if (o != null) {
                     Element fact = new Element("Factory", "");
-                    fact.addAttribute(new Attribute("Name", ((ComponentInstance) o).getComponentDescription().getName()));
+                    fact.addAttribute(new Attribute("Name", ((ComponentInstance) o).getFactory().getName()));
                     service.addElement(fact);
                 }
             }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
index e998b2a..324a85e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
@@ -24,7 +24,7 @@
 import java.util.Properties;
 
 import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
@@ -38,14 +38,10 @@
 public class ServiceInstantiatorHandler extends CompositeHandler {
 
     /**
-     * Composite Manager.
-     */
-    private CompositeManager m_manager;
-
-    /**
      * Is the handler valid ?
+     * (Lifecycle controller)
      */
-    private boolean m_isValid = false;
+    private boolean m_isValid;
 
     /**
      * List of instances to manage.
@@ -55,25 +51,27 @@
     /**
      * Configure the handler.
      * 
-     * @param im : the instance manager
      * @param metadata : the metadata of the component
      * @param conf : the instance configuration
+     * @throws ConfigurationException : the specification attribute is missing
      * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
      * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(CompositeManager im, Element metadata, Dictionary conf) {
-        m_manager = im;
+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
         Element[] services = metadata.getElements("service");
         for (int i = 0; i < services.length; i++) {
+            if (!services[i].containsAttribute("specification")) {
+                throw new ConfigurationException("Malformed service : the specification attribute is mandatory", getCompositeManager().getFactory().getName());
+            }
             String spec = services[i].getAttribute("specification");
-            String filter = "(&(objectClass=" + Factory.class.getName() + ")(!(service.pid=" + m_manager.getComponentDescription().getName() + ")))"; // Cannot reinstantiate yourself
+            String filter = "(&(objectClass=" + Factory.class.getName() + ")(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself
             if (services[i].containsAttribute("filter")) {
-                String classnamefilter = "(&(objectClass=" + Factory.class.getName() + ")(!(service.pid=" + m_manager.getComponentDescription().getName() + ")))"; // Cannot reinstantiate yourself
-                filter = "";
-                if (!services[i].getAttribute("filter").equals("")) {
-                    filter = "(&" + classnamefilter + services[i].getAttribute("filter") + ")";
-                } else {
+                String classnamefilter = "(&(objectClass=" + Factory.class.getName() + ")(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself
+                filter = null;
+                if ("".equals(services[i].getAttribute("filter"))) {
                     filter = classnamefilter;
+                } else {
+                    filter = "(&" + classnamefilter + services[i].getAttribute("filter") + ")";
                 }
             }
             Properties prop = new Properties();
@@ -93,9 +91,6 @@
             SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, filter);
             m_instances.add(inst);
         }
-        if (m_instances.size() > 0) {
-            m_manager.register(this);
-        }
     }
 
     /**
@@ -110,7 +105,7 @@
             inst.start();
         }
 
-        m_isValid = isValid();
+        m_isValid = isHandlerValid();
     }
 
     /**
@@ -118,7 +113,7 @@
      * @return true if all created service instances are valid
      * @see org.apache.felix.ipojo.CompositeHandler#isValid()
      */
-    public boolean isValid() {
+    private boolean isHandlerValid() {
         for (int i = 0; i < m_instances.size(); i++) {
             SvcInstance inst = (SvcInstance) m_instances.get(i);
             if (!inst.isSatisfied()) {
@@ -146,8 +141,7 @@
      */
     public void validate() {
         if (!m_isValid) {
-            if (isValid()) {
-                m_manager.checkInstanceState();
+            if (isHandlerValid()) {
                 m_isValid = true;
             }
         }
@@ -158,8 +152,7 @@
      */
     public void invalidate() {
         if (m_isValid) {
-            if (!isValid()) {
-                m_manager.checkInstanceState();
+            if (!isHandlerValid()) {
                 m_isValid = false;
             }
         }
@@ -171,15 +164,7 @@
      * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
      */
     public HandlerDescription getDescription() {
-        return new ServiceInstantiatorDescription(this.getClass().getName(), isValid(), m_instances);
-    }
-
-    /**
-     * Get the composite manager.
-     * @return the composite manager.
-     */
-    protected CompositeManager getManager() {
-        return m_manager;
+        return new ServiceInstantiatorDescription(this, m_instances);
     }
     
     public List getInstances() {
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
index aa0d866..c292eae 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
@@ -27,14 +27,16 @@
 import java.util.Set;
 
 import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.MissingHandlerException;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.UnacceptableConfiguration;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -43,7 +45,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class SvcInstance implements ServiceListener {
+public class SvcInstance implements TrackerCustomizer {
 
     /**
      * Required specification.
@@ -86,13 +88,12 @@
     private boolean m_isValid = false;
 
     /**
-     * String form of the factory filter.
+     * Tracker used to track required factory.
      */
-    private String m_filterStr;
+    private Tracker m_tracker;
 
     /**
      * Constructor.
-     * 
      * @param h : the handler.
      * @param spec : required specification.
      * @param conf : instance configuration.
@@ -102,42 +103,24 @@
      */
     public SvcInstance(ServiceInstantiatorHandler h, String spec, Dictionary conf, boolean isAgg, boolean isOpt, String filt) {
         m_handler = h;
-        m_context = h.getManager().getServiceContext();
+        m_context = h.getCompositeManager().getServiceContext();
         m_specification = spec;
         m_configuration = conf;
         m_isAggregate = isAgg;
         m_isOptional = isOpt;
-        m_filterStr = filt;
+        try {
+            m_tracker  = new Tracker(m_context, h.getCompositeManager().getContext().createFilter(filt), this);
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
     }
 
     /**
      * Start the service instance.
-     * 
      * @param sc
      */
     public void start() {
-        initFactoryList();
-        // Register factory listener
-        try {
-            m_context.addServiceListener(this, m_filterStr);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace(); // Should not happens
-        }
-
-        // Initialize the instances
-        if (m_usedRef.size() > 0) {
-            Set keys = m_usedRef.keySet();
-            Iterator it = keys.iterator();
-            if (m_isAggregate) {
-                while (it.hasNext()) {
-                    ServiceReference ref = (ServiceReference) it.next();
-                    createInstance(ref);
-                }
-            } else {
-                ServiceReference ref = (ServiceReference) it.next();
-                createInstance(ref);
-            }
-        }
+        m_tracker.open();
         m_isValid = isSatisfied();
     }
 
@@ -145,7 +128,8 @@
      * Stop the service instance.
      */
     public void stop() {
-        m_context.removeServiceListener(this);
+        m_tracker.close();
+        
         Set keys = m_usedRef.keySet();
         Iterator it = keys.iterator();
         while (it.hasNext()) {
@@ -156,6 +140,7 @@
             }
         }
         m_usedRef.clear();
+        m_tracker = null;
         m_isValid = false;
     }
 
@@ -166,33 +151,39 @@
     private boolean isAnInstanceCreated() {
         Set keys = m_usedRef.keySet();
         Iterator it = keys.iterator();
-        ServiceReference ref = (ServiceReference) it.next();
-        Object o = m_usedRef.get(ref);
-        return o != null;
+        while (it.hasNext()) {
+            if (m_usedRef.get(it.next()) != null)  {
+                return true;
+            }
+        }
+        return false;
     }
 
     /**
      * Create an instance for the given reference.
-     * @param ref : the service reference to used to create the instance.
+     * The instance is not added inside the map.
+     * @param factory : the factory from which we need to create the instance.
+     * @return the created component instance.
      */
-    private void createInstance(ServiceReference ref) {
-        try {
-            Factory factory = (Factory) m_context.getService(ref);
-            
-            //  Add an unique name if not specified.
-            Properties p = new Properties();
-            Enumeration kk = m_configuration.keys();
-            while (kk.hasMoreElements()) {
-                String k = (String) kk.nextElement();
-                p.put(k, m_configuration.get(k));
-            }
-            ComponentInstance instance = factory.createComponentInstance(p);
-            m_usedRef.put(ref, instance);
-            m_context.ungetService(ref);
-        } catch (Throwable e) {
-            m_handler.getManager().getFactory().getLogger().log(Logger.ERROR,
-                    "A matching factory (" + ref.getProperty("service.pid") + ") seems to refuse the given configuration : " + e.getMessage());
+    private ComponentInstance createInstance(Factory factory) {
+        // Add an unique name if not specified.
+        Properties p = new Properties();
+        Enumeration kk = m_configuration.keys();
+        while (kk.hasMoreElements()) {
+            String k = (String) kk.nextElement();
+            p.put(k, m_configuration.get(k));
         }
+        ComponentInstance instance = null;
+        try {
+            instance = factory.createComponentInstance(p);
+        } catch (UnacceptableConfiguration e) {
+            e.printStackTrace();
+        } catch (MissingHandlerException e) {
+            e.printStackTrace();
+        } catch (ConfigurationException e) {
+            e.printStackTrace();
+        }
+        return instance;
     }
 
     /**
@@ -217,50 +208,18 @@
             m_usedRef.put(ref, instance);
             m_context.ungetService(ref);
         } catch (UnacceptableConfiguration e) {
-            m_handler.getManager().getFactory().getLogger().log(Logger.ERROR,
-                    "A matching factory (" + ref.getProperty("service.pid") + ") seems to refuse the given configuration : " + e.getMessage());
+            m_handler.log(Logger.ERROR, "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
+        } catch (MissingHandlerException e) {
+            m_handler.log(Logger.ERROR, "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
+        } catch (ConfigurationException e) {
+            m_handler.log(Logger.ERROR, "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
         }
     }
 
-    /**
-     * Kill an instance (if exist).
-     * If an instance if created by using the given reference, this reference is disposed.
-     * @param ref : the leaving reference. 
-     */
-    private void stopInstance(ServiceReference ref) {
-        Object o = m_usedRef.get(ref);
-        if (o != null) {
-            ((ComponentInstance) o).dispose();
-        }
-    }
+
 
     /**
-     * Initialize the list of available factory.
-     */
-    public void initFactoryList() {
-        // Initialize factory list
-        try {
-            ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), m_filterStr);
-            if (refs == null) {
-                return;
-            }
-            for (int i = 0; i < refs.length; i++) {
-                ServiceReference ref = refs[i];
-                Factory fact = (Factory) m_context.getService(ref);
-                // Check provided specification & configuration
-                if (match(fact)) {
-                    m_usedRef.put(ref, null);
-                }
-                fact = null;
-                m_context.ungetService(ref);
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace(); // Should not happen
-        }
-    }
-
-    /**
-     * Check if the service instance is satisfed.
+     * Check if the service instance is satisfied.
      * @return true if the service instance if satisfied.
      */
     public boolean isSatisfied() {
@@ -325,58 +284,6 @@
     }
 
     /**
-     * Service Listener Implementation.
-     * @param ev : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent ev) {
-        if (ev.getType() == ServiceEvent.REGISTERED) {
-            // Check the matching
-            Factory fact = (Factory) m_context.getService(ev.getServiceReference());
-            if (match(fact)) {
-                m_usedRef.put(ev.getServiceReference(), null);
-                if (m_isAggregate) { // Create an instance for the new
-                    // factory
-                    createInstance(ev.getServiceReference());
-                    if (!m_isValid) {
-                        m_isValid = true;
-                        m_handler.validate();
-                    }
-                } else {
-                    if (!isAnInstanceCreated()) {
-                        createInstance(ev.getServiceReference());
-                    }
-                    if (!m_isValid) {
-                        m_isValid = true;
-                        m_handler.validate();
-                    }
-                }
-            }
-            fact = null;
-            m_context.ungetService(ev.getServiceReference());
-            return;
-        }
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
-            // Remove the reference is contained
-            Object o = m_usedRef.remove(ev.getServiceReference());
-            if (o != null) {
-                stopInstance(ev.getServiceReference());
-                if (m_usedRef.size() > 0) {
-                    if (!m_isAggregate) {
-                        createNextInstance(); // Create an instance with
-                        // another factory
-                    }
-                } else { // No more candidate
-                    if (!m_isOptional) {
-                        m_isValid = false;
-                        m_handler.invalidate();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Get the required specification.
      * @return the required specification.
      */
@@ -400,4 +307,71 @@
         return m_usedRef;
     }
 
+    /**
+     * A factory potentially matching with the managed instance appears.
+     * @param reference : service reference
+     * @return : true if the factory match
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        Factory fact = (Factory) m_tracker.getService(reference);
+        if (match(fact)) {
+            if (m_isAggregate) { // Create an instance for the new factory
+                m_usedRef.put(reference, createInstance(fact));
+                if (!m_isValid) {
+                    m_isValid = true;
+                    m_handler.validate();
+                }
+            } else {
+                if (!isAnInstanceCreated()) {
+                    m_usedRef.put(reference, createInstance(fact));
+                } else {
+                    m_usedRef.put(reference, null); // Store the reference
+                }
+                if (!m_isValid) {
+                    m_isValid = true;
+                    m_handler.validate();
+                }
+            }
+            m_tracker.ungetService(reference);
+            return true;
+        } else {
+            m_tracker.ungetService(reference);
+            return false;
+        }
+        
+    }
+
+    /**
+     * A used factory was modified.
+     * @param reference : service reference
+     * @param service : object if already get
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) { } 
+        
+    /**
+     * A used factory disappears.
+     * @param reference : service reference
+     * @param service : object if already get
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+     // Remove the reference is contained
+        Object o = m_usedRef.remove(reference);
+        if (o != null) {
+            ((ComponentInstance) o).dispose();
+            if (m_usedRef.size() > 0) {
+                if (!m_isAggregate) {
+                    createNextInstance(); // Create an instance with another factory
+                }
+            } else { // No more candidate
+                if (!m_isOptional) {
+                    m_isValid = false;
+                    m_handler.invalidate();
+                }
+            }
+        }
+    }
+
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
index 2a81edc..c1cb213 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
@@ -33,7 +33,6 @@
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
@@ -95,7 +94,7 @@
             String methodName = mappings[i].getAttribute("method");
             MethodMetadata method = m_specification.getMethodByName(methodName);
             if (method == null) {
-                m_handler.getManager().getFactory().getLogger().log(Logger.ERROR, "The method " + methodName + " does not exist in the specicifation " + spec);
+                m_handler.log(Logger.ERROR, "The method " + methodName + " does not exist in the specicifation " + spec);
                 return;
             }
 
@@ -127,9 +126,9 @@
         for (int i = 0; i < m_handler.getInstanceType().size(); i++) {
             String type = (String) m_handler.getInstanceType().get(i);
             try {
-                ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(" + Constants.SERVICE_PID + "=" + type + ")");
+                ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(factory.name=" + type + ")");
                 if (refs == null) {
-                    m_handler.getManager().getFactory().getLogger().log(Logger.ERROR, "The factory " + type + " is not available, cannot check the composition");
+                    m_handler.log(Logger.ERROR, "The factory " + type + " is not available, cannot check the composition");
                     throw new CompositionException("The factory " + type + " needs to be available to check the composition");
                 } else {
                     String className = (String) refs[0].getProperty("component.class");
@@ -142,9 +141,9 @@
                     index++;
                 }
             } catch (InvalidSyntaxException e) {
-                m_handler.getManager().getFactory().getLogger().log(Logger.ERROR, "A LDAP filter is not valid : " + e.getMessage());
+                m_handler.log(Logger.ERROR, "A LDAP filter is not valid : " + e.getMessage());
             } catch (ClassNotFoundException e) {
-                m_handler.getManager().getFactory().getLogger().log(Logger.ERROR, "The implementation class of a component cannot be loaded : " + e.getMessage());
+                m_handler.log(Logger.ERROR, "The implementation class of a component cannot be loaded : " + e.getMessage());
             }
         }
 
@@ -207,7 +206,7 @@
             if (!found) { // If not found looks inside method contained in services.
                 keys = availableSvcMethods.keySet(); // Look first in methods contained in the glue code
                 it = keys.iterator();
-                while (it.hasNext() & !found) {
+                while (!found && it.hasNext()) {
                     MethodMetadata met = (MethodMetadata) it.next();
                     if (met.equals(method)) {
                         found = true;
@@ -216,7 +215,7 @@
                         method.setDelegation(field);
                         // Test optional
                         if (field.isOptional() && !method.getExceptions().contains("java/lang/UnsupportedOperationException")) {
-                            m_handler.getManager().getFactory().getLogger().log(Logger.WARNING, "The method " + method.getMethodName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");
+                            m_handler.log(Logger.WARNING, "The method " + method.getMethodName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");
                         }
                     }
                 }
@@ -243,7 +242,7 @@
         } catch (IOException e) {
             e.printStackTrace();
         }
-        return null;
+        return new byte[0];
     }
 
     /**
@@ -257,6 +256,9 @@
         Attribute factory = new Attribute("factory", "false");
         elem.addAttribute(className);
         elem.addAttribute(factory);
+        
+        // Add architcture for debug
+        elem.addAttribute(new Attribute("architecture", "true"));
 
         // Provides
         Element provides = new Element("provides", "");
@@ -274,7 +276,7 @@
                 if (field.getSpecification().isOptional()) {
                     dep.addAttribute(new Attribute("optional", "true"));
                 }
-                dep.addAttribute(new Attribute("filter", "(!(service.pid=" + in + "))"));
+                dep.addAttribute(new Attribute("filter", "(!(instance.name=" + in + "))"));
                 elem.addElement(dep);
             }
         }
@@ -294,7 +296,7 @@
 
         // Insert information to metadata
         elem.addElement(m_manipulationMetadata);
-
+        
         return elem;
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
index 1e529dd..c9e4400 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
@@ -169,26 +169,7 @@
             }

         }

 

-        if (!delegator.isAggregate()) {

-            mv.visitVarInsn(ALOAD, 0);

-            mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "L" + delegator.getSpecification().getName().replace('.', '/') + ";");

-

-            // Loads args

-            Type[] args = Type.getArgumentTypes(desc);

-            for (int i = 0; i < args.length; i++) {

-                writeLoad(args[i], i + 1, mv);

-            }

-

-            // Invoke

-            if (delegator.getSpecification().isInterface()) {

-                mv.visitMethodInsn(INVOKEINTERFACE, delegator.getSpecification().getName().replace('.', '/'), name, desc);

-            } else {

-                mv.visitMethodInsn(INVOKEVIRTUAL, delegator.getSpecification().getName().replace('.', '/'), name, desc);

-            }

-

-            // Return

-            writeReturn(Type.getReturnType(desc), mv);

-        } else {

+        if (delegator.isAggregate()) {

             if (method.getPolicy() == MethodMetadata.ONE_POLICY) {

                 // Aggregate and One Policy

                 mv.visitVarInsn(ALOAD, 0);

@@ -254,6 +235,25 @@
                 mv.visitLabel(l5b);

                 mv.visitInsn(RETURN);

             }

+        } else {

+            mv.visitVarInsn(ALOAD, 0);

+            mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "L" + delegator.getSpecification().getName().replace('.', '/') + ";");

+

+            // Loads args

+            Type[] args = Type.getArgumentTypes(desc);

+            for (int i = 0; i < args.length; i++) {

+                writeLoad(args[i], i + 1, mv);

+            }

+

+            // Invoke

+            if (delegator.getSpecification().isInterface()) {

+                mv.visitMethodInsn(INVOKEINTERFACE, delegator.getSpecification().getName().replace('.', '/'), name, desc);

+            } else {

+                mv.visitMethodInsn(INVOKEVIRTUAL, delegator.getSpecification().getName().replace('.', '/'), name, desc);

+            }

+

+            // Return

+            writeReturn(Type.getReturnType(desc), mv);

         }

 

         mv.visitMaxs(0, 0);

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
index 39ddd2e..994f01e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
@@ -24,13 +24,14 @@
 import org.apache.felix.ipojo.ComponentFactory;
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.MissingHandlerException;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.UnacceptableConfiguration;
 import org.apache.felix.ipojo.composite.instance.InstanceHandler;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 
 /**
  * Composite Provided Service.
@@ -96,7 +97,7 @@
      * @param name : name of this provided service.
      */
     public ProvidedService(ProvidedServiceHandler handler, Element element, String name) {
-        m_manager = handler.getManager();
+        m_manager = handler.getCompositeManager();
         m_scope = m_manager.getServiceContext();
         m_context = m_manager.getContext();
         m_composition = new CompositionMetadata(m_manager.getContext(), element, handler, name);
@@ -110,7 +111,7 @@
     public void start() throws CompositionException {
         m_composition.buildMapping();
         
-        m_instanceName = m_composition.getSpecificationMetadata().getName() + "Provider";
+        m_instanceName = m_composition.getSpecificationMetadata().getName() + "Provider-Gen";
         m_clazz = m_composition.buildPOJO();
         m_metadata = m_composition.buildMetadata(m_instanceName);
 
@@ -119,7 +120,7 @@
         m_factory.start();
 
         // Create the exports
-        m_exports = new ServiceExporter(m_composition.getSpecificationMetadata().getName(), "(" + Constants.SERVICE_PID + "=" + m_instanceName + ")", false, false,
+        m_exports = new ServiceExporter(m_composition.getSpecificationMetadata().getName(), "(instance.name=" + m_instanceName + ")", false, false,
                 m_scope, m_context, this);
         m_exports.start();
     }
@@ -189,10 +190,13 @@
                 }
             }
             try {
-                m_instance = m_factory.createComponentInstance(p, m_scope);
+                m_instance = m_factory.createComponentInstance(p, m_manager.getServiceContext());
             } catch (UnacceptableConfiguration e) {
                 e.printStackTrace();
-                return;
+            } catch (MissingHandlerException e) {
+                e.printStackTrace();
+            } catch (ConfigurationException e) {
+                e.printStackTrace();
             }
         }
     }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
index b0b93a2..56a64b9 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
@@ -25,11 +25,15 @@
 
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.HandlerManager;
+import org.apache.felix.ipojo.IPojoConfiguration;
 import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.composite.instance.InstanceHandler;
-import org.apache.felix.ipojo.composite.service.importer.ImportExportHandler;
+import org.apache.felix.ipojo.composite.service.importer.ImportHandler;
 import org.apache.felix.ipojo.composite.service.importer.ServiceImporter;
 import org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler;
 import org.apache.felix.ipojo.composite.service.instantiator.SvcInstance;
@@ -38,6 +42,7 @@
 import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 
 /**
  * Composite Provided Service Handler.
@@ -46,11 +51,6 @@
 public class ProvidedServiceHandler extends CompositeHandler {
 
     /**
-     * Reference on the instance.
-     */
-    private CompositeManager m_manager;
-
-    /**
      * External context.
      */
     private BundleContext m_context;
@@ -66,7 +66,8 @@
     private List m_managedServices = new ArrayList();
 
     /**
-     * Handler validity. False if
+     * Handler validity.
+     * (Lifecycle controller)
      */
     private boolean m_valid = false;
 
@@ -76,40 +77,42 @@
     private List m_types;
 
     /**
+     * Initialize the component type.
+     * @param cd : component type description to populate.
+     * @param metadata : component type metadata.
+     * @throws ConfigurationException : metadata are incorrect.
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     */
+    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+        Element[] provides = metadata.getElements("provides", "");
+        for (int i = 0; i < provides.length; i++) {
+            if (provides[i].containsAttribute("specification")) {
+                String spec = provides[i].getAttribute("specification");
+                cd.addProvidedServiceSpecification(spec);
+            } else {
+                throw new ConfigurationException("Malformed provides : the specification attribute is mandatory", getCompositeManager().getFactory().getName());
+            }
+        }
+    }
+
+    /**
      * Configure the handler.
-     * 
-     * @param im : the instance manager
      * @param metadata : the metadata of the component
      * @param configuration : the instance configuration
      * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
      * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(CompositeManager im, Element metadata, Dictionary configuration) {
-        m_manager = im;
-        m_context = im.getContext();
+    public void configure(Element metadata, Dictionary configuration) {
+        m_context = getCompositeManager().getContext();
 
         // Get composition metadata
         Element[] provides = metadata.getElements("provides", "");
-        if (provides.length == 0) {
-            return;
-        }
-        
+        if (provides.length == 0) { return; }
+
         for (int i = 0; i < provides.length; i++) {
             ProvidedService ps = new ProvidedService(this, provides[i], "" + i);
             m_managedServices.add(ps);
-            // Check requirements against the service specification
-            if (!checkServiceSpecification(ps)) {
-                return;
-            }
-            im.getComponentDescription().addProvidedServiceSpecification(ps.getSpecification());
         }
-
-        // Compute imports and instances
-        computeAvailableServices();
-        computeAvailableTypes();
-
-        
-        im.register(this);
     }
 
     /**
@@ -118,26 +121,22 @@
      * @see org.apache.felix.ipojo.CompositeHandler#start()
      */
     public void start() {
+        // Compute imports and instances
+        computeAvailableServices();
+        computeAvailableTypes();
+        
         for (int i = 0; i < m_managedServices.size(); i++) {
             ProvidedService ps = (ProvidedService) m_managedServices.get(i);
             try {
+                checkServiceSpecification(ps);
                 ps.start();
             } catch (CompositionException e) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "Cannot start the provided service handler", e);
-                m_valid = false;
+                log(Logger.ERROR, "Cannot start the provided service handler", e);
+                if (m_valid) { m_valid = false; }
                 return;
             }
         }
-        m_valid  = true;
-    }
-    
-    /**
-     * Check the handler validity.
-     * @return true if the handler is valid.
-     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
-     */
-    public boolean isValid() {
-        return m_valid;
+        m_valid = true;
     }
 
     /**
@@ -166,7 +165,7 @@
             return;
         }
 
-        // If the new state is VALID => regiter all the services
+        // If the new state is VALID => register all the services
         if (state == ComponentInstance.VALID) {
             for (int i = 0; i < m_managedServices.size(); i++) {
                 ProvidedService ps = (ProvidedService) m_managedServices.get(i);
@@ -176,10 +175,6 @@
         }
     }
 
-    protected CompositeManager getManager() {
-        return m_manager;
-    }
-
     /**
      * Build the list of available specification.
      * @return the list of available specification.
@@ -193,15 +188,15 @@
      */
     private void computeAvailableServices() {
         // Get instantiated services :
-        ImportExportHandler ih = (ImportExportHandler) m_manager.getCompositeHandler(ImportExportHandler.class.getName());
-        ServiceInstantiatorHandler sh = (ServiceInstantiatorHandler) m_manager.getCompositeHandler(ServiceInstantiatorHandler.class.getName());
-        
+        ImportHandler ih = (ImportHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
+        ServiceInstantiatorHandler sh = (ServiceInstantiatorHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":service");
+
         for (int i = 0; sh != null && i < sh.getInstances().size(); i++) {
             SvcInstance svc = (SvcInstance) sh.getInstances().get(i);
             String itf = svc.getSpecification();
             boolean agg = svc.isAggregate();
             boolean opt = svc.isOptional();
-            
+
             SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
             m_services.add(sm);
         }
@@ -211,26 +206,23 @@
             String itf = si.getSpecification();
             boolean agg = si.isAggregate();
             boolean opt = si.isOptional();
-            
+
             SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
             m_services.add(sm);
         }
     }
-    
+
     /**
      * Check composite requirement against service specification requirement is available.
      * @param ps : the provided service to check
-     * @return true if the composite is a correct implementation of the service
+     * @throws CompositionException : occurs if the specification field of the service specification cannot be analyzed correctly.
      */
-    private boolean checkServiceSpecification(ProvidedService ps) {
+    private void checkServiceSpecification(ProvidedService ps) throws CompositionException {
         try {
-            Class spec = m_manager.getFactory().loadClass(ps.getSpecification());
-            Field specField = spec.getField("specification");     
+            Class spec = getCompositeManager().getFactory().loadClass(ps.getSpecification());
+            Field specField = spec.getField("specification");
             Object o = specField.get(null);
-            if (!(o instanceof String)) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The specification field of the service specification " + ps.getSpecification() + " need to be a String");                                                                                                                                                                    
-                return false;
-            } else {
+            if (o instanceof String) {
                 Element specification = ManifestMetadataParser.parse((String) o);
                 Element[] reqs = specification.getElements("requires");
                 for (int j = 0; j < reqs.length; j++) {
@@ -239,128 +231,135 @@
                         // Fix service-level dependency flag
                         imp.setServiceLevelDependency();
                     }
-                    if (!isRequirementCorrect(imp, reqs[j])) {
-                        return false;
-                    }
+                    checkRequirement(imp, reqs[j]);
                 }
+            } else {
+                log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The specification field of the service specification " + ps.getSpecification() + " need to be a String");
+                throw new CompositionException("Service Specification checking failed : The specification field of the service specification " + ps.getSpecification() + " need to be a String");
             }
         } catch (NoSuchFieldException e) {
-            return true;  // No specification field
+            return; // No specification field
         } catch (ClassNotFoundException e) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The service specification " + ps.getSpecification() + " cannot be load");                                                                                                                                                                    
-            return false;
+            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The service specification " + ps.getSpecification() + " cannot be load");
+            throw new CompositionException("The service specification " + ps.getSpecification() + " cannot be load : " + e.getMessage());
         } catch (IllegalArgumentException e) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());                                                                                                                                                                    
-            return false;
+            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());
+            throw new CompositionException("The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());
         } catch (IllegalAccessException e) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());                                                                                                                                                                    
-            return false;
+            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());
+            throw new CompositionException("The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());
         } catch (ParseException e) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " does not contain a valid String : " + e.getMessage());                                                                                                                                                                    
-            return false;
+            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " does not contain a valid String : " + e.getMessage());
+            throw new CompositionException("The field 'specification' of the service specification " + ps.getSpecification() + " does not contain a valid String : " + e.getMessage());
         }
-        return true;
     }
-    
+
     /**
      * Look for the implementation (i.e. composite) requirement for the given service-level requirement metadata.
      * @param element : the service-level requirement metadata
      * @return the ServiceImporter object, null if not found or if the DependencyHandler is not plugged to the instance
      */
     private ServiceImporter getAttachedRequirement(Element element) {
-        ImportExportHandler ih = (ImportExportHandler) m_manager.getCompositeHandler(ImportExportHandler.class.getName());
-        if (ih == null) { 
-            return null;
-        }
-        
+        ImportHandler ih = (ImportHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
+        if (ih == null) { return null; }
+
         if (element.containsAttribute("id")) {
             // Look for dependency Id
             String id = element.getAttribute("id");
             for (int i = 0; i < ih.getRequirements().size(); i++) {
                 ServiceImporter imp = (ServiceImporter) ih.getRequirements().get(i);
-                if (imp.getId().equals(id)) {
-                    return imp; 
-                }
+                if (imp.getId().equals(id)) { return imp; }
             }
         }
-        
+
         // If not found or no id, look for a dependency with the same specification
         String requirement = element.getAttribute("specification");
         for (int i = 0; i < ih.getRequirements().size(); i++) {
             ServiceImporter imp = (ServiceImporter) ih.getRequirements().get(i);
-            if (imp.getSpecification().equals(requirement)) {
-                return imp; 
-            }
+            if (imp.getSpecification().equals(requirement)) { return imp; }
         }
-        
         return null;
     }
-    
+
     /**
      * Check the correctness of the composite requirement against the service level dependency.
      * @param imp : requirement to check
      * @param elem : service-level dependency metadata
-     * @return true if the dependency is correct, false otherwise
+     * @throws CompositionException : occurs if the requirement does not match with service-level specification requirement
      */
-    private boolean isRequirementCorrect(ServiceImporter imp, Element elem) {
+    private void checkRequirement(ServiceImporter imp, Element elem) throws CompositionException {
         boolean opt = false;
         if (elem.containsAttribute("optional") && elem.getAttribute("optional").equalsIgnoreCase("true")) {
             opt = true;
         }
-        
+
         boolean agg = false;
         if (elem.containsAttribute("aggregate") && elem.getAttribute("aggregate").equalsIgnoreCase("true")) {
             agg = true;
         }
 
         if (imp == null) {
-            //TODO do we need to add the requirement for optional service-level dependency ?
             // Add the missing requirement
-            ImportExportHandler ih = (ImportExportHandler) m_manager.getCompositeHandler(ImportExportHandler.class.getName());
+            ImportHandler ih = (ImportHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
             if (ih == null) {
-                // Add the importer handler 
-                ih = new ImportExportHandler();
-                ih.configure(m_manager, new Element("composite", "") , null); // Enter fake info in the configure method.
-                m_manager.register(ih);
+                // Look for the import handler factory
+                HandlerManager ci = null;
+                try {
+                    ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(&(handler.name=requires)(handler.namespace=" + IPojoConfiguration.IPOJO_NAMESPACE + ")(handler.type=composite))");
+                    Factory factory = (Factory) m_context.getService(refs[0]);
+                    ci = (HandlerManager) factory.createComponentInstance(null, getCompositeManager().getServiceContext());
+                } catch (Exception e) {
+                    e.printStackTrace(); // Should not happen
+                }
+                // Add the required handler 
+                try {
+                    ci.init(getCompositeManager(), new Element("composite", ""), null);
+                } catch (ConfigurationException e) {
+                    log(Logger.ERROR, "Internal error : cannot configure the Import Handler : " + e.getMessage());
+                    throw new CompositionException("Internal error : cannot configure the Import Handler : " + e.getMessage());
+                }
+                ih = (ImportHandler) ci.getHandler();
+                getCompositeManager().addCompositeHandler(ci);
             }
             String spec = elem.getAttribute("specification");
-            String filter = "(&(objectClass=" + spec + ")(!(service.pid=" + m_manager.getInstanceName() + ")))"; // Cannot import yourself
+            String filter = "(&(objectClass=" + spec + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
             if (elem.containsAttribute("filter")) {
-                if (!elem.getAttribute("filter").equals("")) {
+                if (!"".equals(elem.getAttribute("filter"))) {
                     filter = "(&" + filter + elem.getAttribute("filter") + ")";
                 }
             }
-            ServiceImporter si = new ServiceImporter(spec, filter, agg, opt, m_manager.getContext(), m_manager.getServiceContext(), PolicyServiceContext.LOCAL, null, ih);
+            
+            ServiceImporter si = new ServiceImporter(spec, filter, agg, opt, getCompositeManager().getContext(), getCompositeManager().getServiceContext(), PolicyServiceContext.LOCAL, null, ih);
             ih.getRequirements().add(si);
-            return true;
+            SpecificationMetadata sm = new SpecificationMetadata(spec, m_context, agg, opt, this);
+            m_services.add(sm); // Update the available types
+            return;
         }
-        
+
         if (imp.isAggregate() && !agg) {
-            getManager().getFactory().getLogger().log(Logger.ERROR, "[" + getManager().getInstanceName() + "] The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
-            return false;
+            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
+            throw new CompositionException("The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
         }
-      
+
         if (elem.containsAttribute("filter")) {
             String filter = elem.getAttribute("filter");
             String filter2 = imp.getFilter();
             if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {
-                getManager().getFactory().getLogger().log(Logger.ERROR, "[" + getManager().getInstanceName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
-                return false;
+                log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
+                throw new CompositionException("The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
             }
         }
-        
-        return true;
     }
 
     public HandlerDescription getDescription() {
-        return new ProvidedServiceHandlerDescription(true, m_managedServices);
+        return new ProvidedServiceHandlerDescription(this, m_managedServices);
     }
-    
+
     /**
      * Build available instance types.
      */
     private void computeAvailableTypes() {
-        InstanceHandler ih = (InstanceHandler) m_manager.getCompositeHandler(InstanceHandler.class.getName());       
+        InstanceHandler ih = (InstanceHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":instance");
         if (ih == null) {
             m_types = new ArrayList();
         } else {
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
index 7fcb727..19256d6 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
@@ -21,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.felix.ipojo.CompositeHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
@@ -40,11 +41,11 @@
     /**
      * Constructor.
      * 
-     * @param isValid : the validity of the provided service handler.
+     * @param h : composite handler.
      * @param ps : The list of Provided Service.
      */
-    public ProvidedServiceHandlerDescription(boolean isValid, List ps) {
-        super(ProvidedServiceHandler.class.getName(), isValid);
+    public ProvidedServiceHandlerDescription(CompositeHandler h, List ps) {
+        super(h);
         m_providedServices = ps;
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
index 6a0a5b1..080c98d 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
@@ -180,7 +180,7 @@
 
     /**
      * Transform service reference property in a dictionary.
-     * Service.PID and Factory.PID are injected too.
+     * instance.name and factory.name are injected too.
      * @param ref : the service reference.
      * @return the dictionary containing all property of the given service reference.
      */
@@ -191,8 +191,8 @@
             prop.put(keys[i], ref.getProperty(keys[i]));
         }
 
-        prop.put(Constants.SERVICE_PID, m_ps.getManager().getInstanceName());
-        prop.put("factory.pid", m_ps.getManager().getFactory().getName());
+        prop.put("instance.name", m_ps.getManager().getInstanceName());
+        prop.put("factory.name", m_ps.getManager().getFactory().getName());
 
         return prop;
     }
@@ -215,7 +215,6 @@
         }
 
         m_records.clear();
-
     }
 
     /**
@@ -293,7 +292,7 @@
      * Manage the arrival of a service.
      * @param ref : the new service reference.
      */
-    private synchronized void arrivalManagement(ServiceReference ref) {
+    private void arrivalManagement(ServiceReference ref) {
         // Check if the new service match
         if (m_filter.match(ref)) {
             // Add it to the record list
@@ -319,7 +318,7 @@
      * Manage the departure of a service.
      * @param ref : the new service reference.
      */
-    private synchronized void departureManagement(ServiceReference ref) {
+    private void departureManagement(ServiceReference ref) {
         List l = getRecordsByRef(ref);
         for (int i = 0; i < l.size(); i++) { // Stop the implied record
             Record rec = (Record) l.get(i);
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
index bc101fc..e0e1b8d 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
@@ -64,7 +64,7 @@
     private boolean m_isInterface = true;
     
     /**
-     * Componenet Type.
+     * Component Type.
      */
     private String m_componentType = null;
 
@@ -97,7 +97,7 @@
             cr.accept(msv, ClassReader.SKIP_FRAMES);
             is.close();
         } catch (IOException e) {
-            m_handler.getManager().getFactory().getLogger().log(Logger.ERROR, "Cannot open " + name + " : " + e.getMessage());
+            m_handler.log(Logger.ERROR, "Cannot open " + name + " : " + e.getMessage());
             return;
         }
     
@@ -126,7 +126,7 @@
     /**
      * Constructor.
      * @param c : class
-     * @param type : componenet type
+     * @param type : component type
      * @param psd : the parent handler
      */
     public SpecificationMetadata(Class c, String type, ProvidedServiceHandler psd) {
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
index a6234db..afa138e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
@@ -19,34 +19,19 @@
 package org.apache.felix.ipojo.handlers.architecture;
 
 import java.util.Dictionary;
-import java.util.Properties;
 
-import org.apache.felix.ipojo.Handler;
-import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.metadata.Element;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
+import org.apache.felix.ipojo.util.Logger;
 
 /**
- * Achtiecture Handler : do reflection on your component.
+ * Architecture Handler : do reflection on your component.
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ArchitectureHandler extends Handler implements Architecture {
-
-    /**
-     * Instance Manager.
-     */
-    private InstanceManager m_manager;
-
-    /**
-     * Service Registration of the Architecture service provided by this
-     * handler.
-     */
-    private ServiceRegistration m_sr;
+public class ArchitectureHandler extends PrimitiveHandler implements Architecture {
 
     /**
      * Name of the component.
@@ -56,56 +41,26 @@
     /**
      * Configure the handler.
      * 
-     * @param im : the instance manager
      * @param metadata : the metadata of the component
      * @param configuration : the instance configuration
-     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager,
-     * org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(InstanceManager im, Element metadata, Dictionary configuration) {
-        if (metadata.containsAttribute("architecture")) {
-            String isArchitectureEnabled = (metadata.getAttribute("architecture")).toLowerCase();
-            if (isArchitectureEnabled.equalsIgnoreCase("true")) {
-                im.register(this);
-            }
-        }
-
+    public void configure(Element metadata, Dictionary configuration) {
         m_name = (String) configuration.get("name");
-
-        m_manager = im;
     }
 
     /**
      * Stop method.
-     * Unregister the service if published.
      * @see org.apache.felix.ipojo.Handler#stop()
      */
-    public void stop() {
-        if (m_sr != null) {
-            m_sr.unregister();
-            m_sr = null;
-        }
-    }
+    public void stop() {  }
 
     /**
      * Start method.
-     * Register the service.
      * @see org.apache.felix.ipojo.Handler#start()
      */
-    public void start() {
-        // Unregister the service if already registred
-        if (m_sr != null) {
-            m_sr.unregister();
-        }
-
-        // Register the ManagedService
-        BundleContext bc = m_manager.getContext();
-        Dictionary properties = new Properties();
-        properties.put("Component.Implementation.Class", m_manager.getClassName());
-        properties.put(Constants.SERVICE_PID, m_name);
-
-        m_sr = bc.registerService(Architecture.class.getName(), this, properties);
-
+    public void start() {  
+        log(Logger.INFO, "Start architecture handler with " + m_name + " name");
     }
 
     /**
@@ -114,7 +69,6 @@
      * @see org.apache.felix.ipojo.architecture.Architecture#getDescription()
      */
     public InstanceDescription getInstanceDescription() {
-        return m_manager.getInstanceDescription();
+        return getInstanceManager().getInstanceDescription();
     }
-
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
index 758127b..822fb69 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
@@ -46,7 +46,7 @@
     /**
      * Method of the property.
      */
-    private String m_method;
+    private Callback m_method;
 
     /**
      * Value of the property.
@@ -74,12 +74,10 @@
      * @param type : the type of the property
      * @param ch : configuration handler managing this configurable property
      */
-    public ConfigurableProperty(String name, String field, String method, String value, String type,
-            ConfigurationHandler ch) {
+    public ConfigurableProperty(String name, String field, String method, String value, String type, ConfigurationHandler ch) {
         m_handler = ch;
 
         m_field = field;
-        m_method = method;
 
         if (name != null) {
             m_name = name;
@@ -96,52 +94,54 @@
             setValue(value, type);
         }
 
+        if (method != null) {
+            m_method = new Callback(method, new String[] { m_type.getName() }, false, m_handler.getInstanceManager());
+        }
+
     }
 
     /**
      * Set the value of the property.
-     * 
      * @param strValue : value of the property (String)
      * @param type : type of the property
      */
     private void setValue(String strValue, String type) {
         Object value = null;
-        
+
         // Syntactic sugar to avoid writing java.lang.String
-        if (type.equals("string") || type.equals("String")) {
+        if ("string".equals(type) || "String".equals(type)) {
             value = new String(strValue);
             m_type = java.lang.String.class;
         }
-		
         if (type.equals("boolean")) {
             value = new Boolean(strValue);
             m_type = Boolean.TYPE;
         }
-        if (type.equals("byte")) {
+        if ("byte".equals(type)) {
             value = new Byte(strValue);
             m_type = Byte.TYPE;
         }
-        if (type.equals("short")) {
+        if ("short".equals(type)) {
             value = new Short(strValue);
             m_type = Short.TYPE;
         }
-        if (type.equals("int")) {
+        if ("int".equals(type)) {
             value = new Integer(strValue);
             m_type = Integer.TYPE;
         }
-        if (type.equals("long")) {
+        if ("long".equals(type)) {
             value = new Long(strValue);
             m_type = Long.TYPE;
         }
-        if (type.equals("float")) {
+        if ("float".equals(type)) {
             value = new Float(strValue);
             m_type = Float.TYPE;
         }
-        if (type.equals("double")) {
+        if ("double".equals(type)) {
             value = new Double(strValue);
             m_type = Double.TYPE;
         }
-        if (type.equals("char")) {
+        if ("char".equals(type)) {
             value = new Character(strValue.charAt(0));
             m_type = Character.TYPE;
         }
@@ -161,24 +161,19 @@
                 Constructor cst = m_type.getConstructor(new Class[] { String.class });
                 value = cst.newInstance(new Object[] { strValue });
             } catch (ClassNotFoundException e) {
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                        "Class not found exception in setValue on " + type + " : " + e.getMessage());
+                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Class not found exception in setValue on " + type + " : " + e.getMessage());
                 return;
             } catch (SecurityException e) {
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                        "Security excption in setValue on " + type + " : " + e.getMessage());
+                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Security excption in setValue on " + type + " : " + e.getMessage());
                 return;
             } catch (NoSuchMethodException e) {
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                        "Constructor not found exeption in setValue on " + type + " : " + e.getMessage());
+                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Constructor not found exeption in setValue on " + type + " : " + e.getMessage());
                 return;
             } catch (IllegalArgumentException e) {
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                        "Argument problem to call the constructor of the type " + type);
+                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Argument problem to call the constructor of the type " + type);
                 return;
             } catch (InstantiationException e) {
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                        "Instantiation problem  " + type);
+                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Instantiation problem  " + type);
                 return;
             } catch (IllegalAccessException e) {
                 m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Illegal Access " + type);
@@ -200,7 +195,7 @@
      * @param values : new property value
      */
     private void setArrayValue(String internalType, String[] values) {
-        if (internalType.equals("string") || internalType.equals("String")) {
+        if ("string".equals(internalType) || "String".equals(internalType)) {
             String[] str = new String[values.length];
             for (int i = 0; i < values.length; i++) {
                 str[i] = new String(values[i]);
@@ -209,7 +204,7 @@
             m_type = new String[0].getClass();
             return;
         }
-        if (internalType.equals("boolean")) {
+        if ("boolean".equals(internalType)) {
             boolean[] bool = new boolean[values.length];
             for (int i = 0; i < values.length; i++) {
                 bool[i] = new Boolean(values[i]).booleanValue();
@@ -218,7 +213,7 @@
             m_type = new boolean[0].getClass();
             return;
         }
-        if (internalType.equals("byte")) {
+        if ("byte".equals(internalType)) {
             byte[] byt = new byte[values.length];
             for (int i = 0; i < values.length; i++) {
                 byt[i] = new Byte(values[i]).byteValue();
@@ -227,7 +222,7 @@
             m_type = new byte[0].getClass();
             return;
         }
-        if (internalType.equals("short")) {
+        if ("short".equals(internalType)) {
             short[] shor = new short[values.length];
             for (int i = 0; i < values.length; i++) {
                 shor[i] = new Short(values[i]).shortValue();
@@ -236,7 +231,7 @@
             m_type = new short[0].getClass();
             return;
         }
-        if (internalType.equals("int")) {
+        if ("int".equals(internalType)) {
             int[] in = new int[values.length];
             for (int i = 0; i < values.length; i++) {
                 in[i] = new Integer(values[i]).intValue();
@@ -245,7 +240,7 @@
             m_type = new int[0].getClass();
             return;
         }
-        if (internalType.equals("long")) {
+        if ("long".equals(internalType)) {
             long[] ll = new long[values.length];
             for (int i = 0; i < values.length; i++) {
                 ll[i] = new Long(values[i]).longValue();
@@ -254,7 +249,7 @@
             m_type = new long[0].getClass();
             return;
         }
-        if (internalType.equals("float")) {
+        if ("float".equals(internalType)) {
             float[] fl = new float[values.length];
             for (int i = 0; i < values.length; i++) {
                 fl[i] = new Float(values[i]).floatValue();
@@ -263,7 +258,7 @@
             m_type = new float[0].getClass();
             return;
         }
-        if (internalType.equals("double")) {
+        if ("double".equals(internalType)) {
             double[] dl = new double[values.length];
             for (int i = 0; i < values.length; i++) {
                 dl[i] = new Double(values[i]).doubleValue();
@@ -272,7 +267,7 @@
             m_type = new double[0].getClass();
             return;
         }
-        if (internalType.equals("char")) {
+        if ("char".equals(internalType)) {
             char[] dl = new char[values.length];
             for (int i = 0; i < values.length; i++) {
                 dl[i] = values[i].toCharArray()[0];
@@ -295,26 +290,19 @@
             m_type = ob.getClass();
             return;
         } catch (ClassNotFoundException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "Class not found exception in setValue on " + internalType);
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Class not found exception in setValue on " + internalType);
         } catch (SecurityException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "Secutiry Exception in setValue on " + internalType);
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Secutiry Exception in setValue on " + internalType);
         } catch (NoSuchMethodException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "Constructor not found exception in setValue on " + internalType);
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Constructor not found exception in setValue on " + internalType);
         } catch (IllegalArgumentException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "Argument problem to call the constructor of the type " + internalType);
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Argument problem to call the constructor of the type " + internalType);
         } catch (InstantiationException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "Instantiation problem  " + internalType);
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Instantiation problem  " + internalType);
         } catch (IllegalAccessException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "Illegal Access Exception in  " + internalType);
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Illegal Access Exception in  " + internalType);
         } catch (InvocationTargetException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "Invocation problem " + internalType);
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Invocation problem " + internalType);
         }
     }
 
@@ -326,8 +314,29 @@
         return m_field;
     }
 
+    /**
+     * Get method name, null if no method.
+     * @return the method name.
+     */
     public String getMethod() {
-        return m_method;
+        if (m_method == null) { return null; }
+        return m_method.getMethod();
+    }
+
+    /**
+     * Check if the property has a method callback.
+     * @return true if the property has a method.
+     */
+    public boolean hasMethod() {
+        return m_method != null;
+    }
+
+    /**
+     * Check if the property has a field.
+     * @return true if the property has a field.
+     */
+    public boolean hasField() {
+        return m_field != null;
     }
 
     public Object getValue() {
@@ -347,57 +356,36 @@
      * Invoke the method (if specified).
      */
     public void invoke() {
-        Callback cb = new Callback(m_method, new String[] { m_type.getName() }, false, m_handler.getInstanceManager());
         try {
-            cb.call(new Object[] { m_value });
+            m_method.call(new Object[] { m_value });
         } catch (NoSuchMethodException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(
-                    Logger.ERROR, "The method " + m_method + " does not exist in the class "
-                            + m_handler.getInstanceManager().getClassName());
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
             return;
         } catch (IllegalAccessException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(
-                    Logger.ERROR,
-                    "The method " + m_method + " is not accessible in the class "
-                            + m_handler.getInstanceManager().getClassName());
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
             return;
         } catch (InvocationTargetException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(
-                    Logger.ERROR,
-                    "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName()
-                            + "thorws an exception : " + e.getMessage());
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName() + "thorws an exception : " + e.getMessage());
             return;
         }
     }
 
     /**
-     * Handler createInstance method. This method is overided to allow delayed
-     * callback invocation.
-     * 
-     * @param instance :
-     *            the created object
-     * @see org.apache.felix.ipojo.Handler#createInstance(java.lang.Object)
+     * Handler createInstance method. This method is overided to allow delayed callback invocation.
+     * @param instance : the created object
+     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
      */
     public void invoke(Object instance) {
-        Callback cb = new Callback(m_method, new String[] { m_type.getName() }, false, m_handler.getInstanceManager());
         try {
-            cb.call(instance, new Object[] { m_value });
+            m_method.call(instance, new Object[] { m_value });
         } catch (NoSuchMethodException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(
-                    Logger.ERROR, "The method " + m_method + " does not exist in the class "
-                            + m_handler.getInstanceManager().getClassName());
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
             return;
         } catch (IllegalAccessException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(
-                    Logger.ERROR,
-                    "The method " + m_method + " is not accessible in the class "
-                            + m_handler.getInstanceManager().getClassName());
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
             return;
         } catch (InvocationTargetException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(
-                    Logger.ERROR,
-                    "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName()
-                            + "throws an exception : " + e.getMessage());
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getMessage());
             return;
         }
     }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index 81f3e01..1e4fd21 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -24,8 +24,10 @@
 import java.util.List;
 import java.util.Properties;
 
-import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.IPojoConfiguration;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
@@ -34,19 +36,12 @@
 import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
 import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.ServiceRegistration;
 
 /**
  * Handler managing the Configuration Admin.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ConfigurationHandler extends Handler {
-
-    /**
-     * Reference on the instance manager.
-     */
-    private InstanceManager m_manager;
+public class ConfigurationHandler extends PrimitiveHandler {
 
     /**
      * List of the configurable fields.
@@ -54,7 +49,7 @@
     private ConfigurableProperty[] m_configurableProperties = new ConfigurableProperty[0];
 
     /**
-     * ProvidedServiceHandler of the component. It is useful to priopagate
+     * ProvidedServiceHandler of the component. It is useful to propagate
      * properties to service registrations.
      */
     private ProvidedServiceHandler m_providedServiceHandler;
@@ -65,7 +60,7 @@
     private Dictionary m_propagated = new Properties();
 
     /**
-     * Properties to propage.
+     * Properties to propagate.
      */
     private Dictionary m_toPropagate = new Properties();
 
@@ -75,44 +70,106 @@
     private boolean m_isConfigurable;
 
     /**
-     * Service registration of the ManagedService provided by this handler.
+     * Initialize the component type.
+     * @param cd : component type description to populate.
+     * @param metadata : component type metadata.
+     * @throws ConfigurationException : metadata are incorrect.
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
      */
-    private ServiceRegistration m_sr;
+    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+        Element[] confs = metadata.getElements("Properties", "");
+        if (confs.length == 0) { return; }
+        Element[] configurables = confs[0].getElements("Property");
+        for (int i = 0; i < configurables.length; i++) {
+            String fieldName = null;
+            String methodName = null;
 
-    /**
-     * Get the instance manager.
-     * @return instance manager of this handler.
-     */
-    protected InstanceManager getInstanceManager() {
-        return m_manager;
+            if (configurables[i].containsAttribute("field")) {
+                fieldName = configurables[i].getAttribute("field");
+            }
+            if (configurables[i].containsAttribute("method")) {
+                methodName = configurables[i].getAttribute("method");
+            }
+
+            if (fieldName != null || methodName != null) {
+                String name = null;
+                if (configurables[i].containsAttribute("name")) {
+                    name = configurables[i].getAttribute("name");
+                } else {
+                    if (fieldName != null) {
+                        name = fieldName;
+                    } else {
+                        name = methodName;
+                    }
+                }
+                String value = null;
+                if (configurables[i].containsAttribute("value")) {
+                    value = configurables[i].getAttribute("value");
+                }
+
+                // Detect the type of the property
+                ManipulationMetadata manipulation = new ManipulationMetadata(metadata);
+                String type = null;
+                if (fieldName != null) {
+                    FieldMetadata fm = manipulation.getField(fieldName);
+                    if (fm == null) { throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation", getInstanceManager().getFactory().getName()); }
+                    type = fm.getFieldType();
+                } else {
+                    MethodMetadata[] mm = manipulation.getMethods(methodName);
+                    if (mm.length != 0) {
+                        if (mm[0].getMethodArguments().length != 1) {
+                            log(Logger.ERROR, "[" + getInstanceManager().getClassName() + "] The method " + methodName + " does not have one argument");
+                            throw new ConfigurationException("Malformed property :  The method " + methodName + " does not have one argument", getInstanceManager().getFactory().getName());
+                        }
+                        if (type != null && !type.equals(mm[0].getMethodArguments()[0])) {
+                            log(Logger.ERROR, "[" + getInstanceManager().getClassName() + "] The field type (" + type + ") and the method type (" + mm[0].getMethodArguments()[0] + ") are not the same.");
+                            throw new ConfigurationException("Malformed property :   The field type (" + type + ") and the method type (" + mm[0].getMethodArguments()[0] + ") are not the same.", getInstanceManager().getFactory().getName());
+                        }
+                        type = mm[0].getMethodArguments()[0];
+                    } else {
+                        // Else, the method is in a super class, look for the type attribute to get the type (if not already discovered)
+                        if (type == null && configurables[i].containsAttribute("type")) {
+                            type = configurables[i].getAttribute("type");
+                        } else {
+                            log(Logger.ERROR, "The type of the property cannot be discovered, please add a 'type' attribute");
+                            return;
+                        }
+                    }
+                }
+
+                if (value != null) {
+                    cd.addProperty(new PropertyDescription(name, type, value));
+                } else {
+                    cd.addProperty(new PropertyDescription(name, type, null));
+                }
+            } else {
+                throw new ConfigurationException("Malformed property : The property need to contain at least a field or a method", getInstanceManager().getFactory().getName());
+            }
+        }
     }
 
     /**
      * Configure the handler.
      * 
-     * @param im : the instance manager
      * @param metadata : the metadata of the component
      * @param configuration : the instance configuration
+     * @throws ConfigurationException : one property metadata is not correct 
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager,
      * org.apache.felix.ipojo.metadata.Element)
      */
-    public void configure(InstanceManager im, Element metadata, Dictionary configuration) {
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
         // Store the component manager
-        m_manager = im;
-        ComponentDescription cd = im.getComponentDescription();
         m_configurableProperties = new ConfigurableProperty[0];
 
-        // Build the hashmap
+        // Build the map
         Element[] confs = metadata.getElements("Properties", "");
-        if (confs.length == 0) {
-            return;
-        }
+        if (confs.length == 0) { return; }
 
         // Check if the component is dynamically configurable
         m_isConfigurable = false;
         // DEPRECATED BLOCK
         if (confs[0].containsAttribute("configurable") && confs[0].getAttribute("configurable").equalsIgnoreCase("true")) {
-            m_manager.getFactory().getLogger().log(Logger.WARNING, "The configurable attribute is deprecated, please use the propagation attribute");
+            log(Logger.WARNING, "The configurable attribute is deprecated, please use the propagation attribute");
             m_isConfigurable = true;
             m_toPropagate = configuration;
         }
@@ -125,19 +182,23 @@
         Element[] configurables = confs[0].getElements("Property");
 
         List ff = new ArrayList();
-        
+
         for (int i = 0; i < configurables.length; i++) {
             String fieldName = null;
             String methodName = null;
-            
-            if (configurables[i].containsAttribute("field")) { fieldName = configurables[i].getAttribute("field"); }
-            if (configurables[i].containsAttribute("method")) { methodName = configurables[i].getAttribute("method"); }
-            
-            if (fieldName == null && methodName == null) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "A configurable property need to have at least a field or a method");
-                return;
+
+            if (configurables[i].containsAttribute("field")) {
+                fieldName = configurables[i].getAttribute("field");
             }
-            
+            if (configurables[i].containsAttribute("method")) {
+                methodName = configurables[i].getAttribute("method");
+            }
+
+            if (fieldName == null && methodName == null) {
+                log(Logger.ERROR, "A configurable property need to have at least a field or a method");
+                throw new ConfigurationException("Malformed property : The property need to contain at least a field or a method", getInstanceManager().getFactory().getName());
+            }
+
             String name = null;
             if (configurables[i].containsAttribute("name")) {
                 name = configurables[i].getAttribute("name");
@@ -167,9 +228,8 @@
             if (fieldName != null) {
                 FieldMetadata fm = manipulation.getField(fieldName);
                 if (fm == null) {
-                    m_manager.getFactory().getLogger().log(Logger.ERROR,
-                            "[" + m_manager.getClassName() + "] The field " + fieldName + " does not exist in the implementation");
-                    return;
+                    log(Logger.ERROR, "[" + getInstanceManager().getClassName() + "] The field " + fieldName + " does not exist in the implementation");
+                    throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation", getInstanceManager().getFactory().getName());
                 }
                 type = fm.getFieldType();
                 ff.add(fm);
@@ -177,35 +237,26 @@
                 MethodMetadata[] mm = manipulation.getMethods(methodName);
                 if (mm.length != 0) {
                     if (mm[0].getMethodArguments().length != 1) {
-                        m_manager.getFactory().getLogger().log(Logger.ERROR,
-                                "[" + m_manager.getClassName() + "] The method " + methodName + " does not have one argument");
-                        return;
+                        log(Logger.ERROR, "[" + getInstanceManager().getClassName() + "] The method " + methodName + " does not have one argument");
+                        throw new ConfigurationException("Malformed property :  The method " + methodName + " does not have one argument", getInstanceManager().getFactory().getName());
                     }
                     if (type != null && !type.equals(mm[0].getMethodArguments()[0])) {
-                        m_manager.getFactory().getLogger().log(Logger.ERROR,
-                                "[" + m_manager.getClassName() + "] The field type (" + type + ") and the method type (" + mm[0].getMethodArguments()[0] + ") are not the same.");
-                        return;
+                        log(Logger.ERROR, "[" + getInstanceManager().getClassName() + "] The field type (" + type + ") and the method type (" + mm[0].getMethodArguments()[0] + ") are not the same.");
+                        throw new ConfigurationException("Malformed property :   The field type (" + type + ") and the method type (" + mm[0].getMethodArguments()[0] + ") are not the same.", getInstanceManager().getFactory().getName());
                     }
                     type = mm[0].getMethodArguments()[0];
                 } else {
-					// Else, the method is in a super class, look for the type attribute to get the type (if not already discovered)
-					if (type == null && configurables[i].containsAttribute("type")) { 
-							type = configurables[i].getAttribute("type"); 
-					} else {
-						m_manager.getFactory().getLogger().log(Logger.ERROR, "The type of the property cannot be discovered, please add a 'type' attribute");
-						return;
-					}
-				}
+                    // Else, the method is in a super class, look for the type attribute to get the type (if not already discovered)
+                    if (type == null && configurables[i].containsAttribute("type")) {
+                        type = configurables[i].getAttribute("type");
+                    } else {
+                        log(Logger.ERROR, "The type of the property cannot be discovered, please add a 'type' attribute");
+                        return;
+                    }
+                }
             }
 
             ConfigurableProperty cp = new ConfigurableProperty(name, fieldName, methodName, value, type, this);
-
-            if (cp.getValue() != null) {
-                cd.addProperty(new PropertyDescription(name, type, cp.getValue().toString()));
-            } else {
-                cd.addProperty(new PropertyDescription(name, type, null));
-            }
-
             addProperty(cp);
         }
 
@@ -223,7 +274,7 @@
                     }
                 }
             }
-            m_manager.register(this, (FieldMetadata[]) ff.toArray(new FieldMetadata[0]), null);
+            getInstanceManager().register(this, (FieldMetadata[]) ff.toArray(new FieldMetadata[0]), null);
         }
     }
 
@@ -242,7 +293,7 @@
      */
     public void start() {
         // Get the provided service handler :
-        m_providedServiceHandler = (ProvidedServiceHandler) m_manager.getHandler(ProvidedServiceHandler.class.getName());
+        m_providedServiceHandler = (ProvidedServiceHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":provides");
 
         // Propagation
         if (m_isConfigurable) {
@@ -253,7 +304,6 @@
         }
     }
 
-
     /**
      * Setter Callback Method.
      * Check if the modified field is a configurable property to update the value.
@@ -287,9 +337,7 @@
     public Object getterCallback(String fieldName, Object value) {
         // Check if the field is a configurable property
         for (int i = 0; i < m_configurableProperties.length; i++) {
-            if (m_configurableProperties[i].getField().equals(fieldName)) {
-                return m_configurableProperties[i].getValue();
-            }
+            if (m_configurableProperties[i].getField().equals(fieldName)) { return m_configurableProperties[i].getValue(); }
         }
         return value;
     }
@@ -301,15 +349,11 @@
      */
     public void stateChanged(int state) {
         if (state == InstanceManager.VALID) {
-            if (m_sr == null) {
-                start();
-            }
+            start();
             return;
         }
         if (state == InstanceManager.INVALID) {
-            if (m_sr != null) {
-                stop();
-            }
+            stop();
             return;
         }
     }
@@ -317,13 +361,11 @@
     /**
      * Add the given property metadata to the property metadata list.
      * 
-     * @param p : property metdata to add
+     * @param p : property metadata to add
      */
     protected void addProperty(ConfigurableProperty p) {
         for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
-            if (m_configurableProperties[i].getName().equals(p.getName())) {
-                return;
-            }
+            if (m_configurableProperties[i].getName().equals(p.getName())) { return; }
         }
 
         if (m_configurableProperties.length > 0) {
@@ -337,16 +379,14 @@
     }
 
     /**
-     * Check if the liste contains the property.
+     * Check if the list contains the property.
      * 
      * @param name : name of the property
      * @return true if the property exist in the list
      */
     protected boolean containsProperty(String name) {
         for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
-            if (m_configurableProperties[i].getName().equals(name)) {
-                return true;
-            }
+            if (m_configurableProperties[i].getName().equals(name)) { return true; }
         }
         return false;
     }
@@ -363,25 +403,25 @@
         while (keysEnumeration.hasMoreElements()) {
             String name = (String) keysEnumeration.nextElement();
             Object value = np.get(name);
-            boolean find = false;
-            // Check if the field is a configurable property
-            for (int i = 0; !find && i < m_configurableProperties.length; i++) {
+            boolean found = false;
+            // Check if the name is a configurable property
+            for (int i = 0; !found && i < m_configurableProperties.length; i++) {
                 if (m_configurableProperties[i].getName().equals(name)) {
-                    // Check if the value has change
+                    // Check if the value has changed
                     if (m_configurableProperties[i].getValue() == null || !m_configurableProperties[i].getValue().equals(value)) {
-                        if (m_configurableProperties[i].getField() != null) {
-                            m_manager.setterCallback(m_configurableProperties[i].getField(), value); // says that the value has changed
+                        if (m_configurableProperties[i].hasField()) {
+                            getInstanceManager().setterCallback(m_configurableProperties[i].getField(), value); // dispatch that the value has changed
                         }
-                        if (m_configurableProperties[i].getMethod() != null) {
+                        if (m_configurableProperties[i].hasMethod()) {
                             m_configurableProperties[i].setValue(value);
                             m_configurableProperties[i].invoke();
                         }
                     }
-                    find = true;
+                    found = true;
                     // Else do nothing
                 }
             }
-            if (!find) {
+            if (!found) {
                 // The property is not a configurable property
                 toPropagate.put(name, value);
             }
@@ -390,7 +430,7 @@
         // Propagation of the properties to service registrations :
         if (m_providedServiceHandler != null && !toPropagate.isEmpty()) {
             m_providedServiceHandler.removeProperties(m_propagated);
-            
+
             // Remove the name props
             toPropagate.remove("name");
 
@@ -398,20 +438,19 @@
             m_propagated = toPropagate;
         }
     }
-    
+
     /**
      * Handler createInstance method.
-     * This method is overided to allow delayed callback invocation.
+     * This method is override to allow delayed callback invocation.
      * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#createInstance(java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
      */
-    public void createInstance(Object instance) {
+    public void objectCreated(Object instance) {
         for (int i = 0; i < m_configurableProperties.length; i++) {
-            if (m_configurableProperties[i].getMethod() != null) {
+            if (m_configurableProperties[i].hasMethod()) {
                 m_configurableProperties[i].invoke(instance);
             }
         }
     }
 
-
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
index 153c276..7638049 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
@@ -29,10 +29,10 @@
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.composite.CompositeServiceContext;
 import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -40,7 +40,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class Dependency implements ServiceListener {
+public class Dependency implements TrackerCustomizer {
 
     /**
      * Dependency State : RESOLVED.
@@ -106,7 +106,7 @@
      * Array of service references.
      * m_ref : Array
      */
-    private List m_references = new ArrayList();
+    //private List m_references = new ArrayList();
     
     /**
      * Array of service reference containing used service references. 
@@ -141,6 +141,11 @@
     private ServiceUsage m_usage = new ServiceUsage();
 
     /**
+     * Service Tracker.
+     */
+    private Tracker m_tracker;
+
+    /**
      * Dependency constructor. After the creation the dependency is not started.
      * 
      * @param dh : the dependency handler managing this dependency
@@ -249,14 +254,14 @@
         return set;
     }
 
-    /**
-     * A dependency is satisfied if it is optional or there is useful references.
-     * 
-     * @return true is the dependency is satisfied
-     */
-    protected boolean isSatisfied() {
-        return m_isOptional || ! m_references.isEmpty();
-    }
+//    /**
+//     * A dependency is satisfied if it is optional or there is useful references.
+//     * 
+//     * @return true is the dependency is satisfied
+//     */
+//    protected boolean isSatisfied() {
+//        return m_isOptional || m_tracker.size() != 0;
+//    }
 
     /**
      * This method is called by the replaced code in the component
@@ -266,185 +271,87 @@
      * the dependency.
      */
     protected Object get() {
-        try {
-            // Initialize the thread local object is not already touched.
-            if (m_usage.getObjects().isEmpty()) {
-                if (isAggregate()) {
-                    m_usage.getReferences().addAll(m_references);
-                    for (int i = 0; i < m_references.size(); i++) {
-                        m_usage.getObjects().add(getService((ServiceReference) m_references.get(i)));
+        // Initialize the thread local object is not already touched.
+        if (m_usage.getObjects().isEmpty()) {
+            if (isAggregate()) {
+                synchronized (m_tracker) {
+                    ServiceReference[] refs = m_tracker.getServiceReferences();
+                    for (int i = 0; refs != null && i < refs.length; i++) {
+                        m_usage.getReferences().add(refs[i]);
+                        m_usage.getObjects().add(getService(refs[i]));
                     }
-                } else {
-                    if (!m_references.isEmpty()) {
-                        m_usage.getReferences().add(m_references.get(0));
-                        m_usage.getObjects().add(getService((ServiceReference) m_references.get(0)));
-                    } else {
-                        // Add a nullable object
-                        // Load the nullable class
-                        String className = m_specification + "Nullable";
-                        Class nullableClazz = m_handler.getNullableClass(className);
+                }
+            } else {
+                if (m_tracker.size() == 0) {
+                    // Load the nullable class
+                    String className = m_specification + "Nullable";
+                    Class nullableClazz = m_handler.getNullableClass(className);
 
-                        if (nullableClazz == null) {
-                            m_handler.getInstanceManager().getFactory().getLogger().log(
-                                    Logger.INFO,
-                                    "[" + m_handler.getInstanceManager().getClassName()
-                                            + "] Cannot load the nullable class to return a dependency object for "
-                                            + m_field + " -> " + m_specification);
+                    if (nullableClazz == null) {
+                        m_handler.log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Cannot load the nullable class to return a dependency object for " + m_field + " -> " + m_specification);
+                        return null;
+                    }
+
+                    // The nullable class is loaded, create the object and add it
+                    Object instance = null;
+                    try {
+                        instance = nullableClazz.newInstance();
+                    } catch (IllegalAccessException e) {
+                        // There is a problem in the dependency resolving (like in stopping method)
+                        if (m_isAggregate) {
+                            m_handler.log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Return an empty array, an exception was throwed in the get method", e);
+                            return Array.newInstance(m_clazz, 0);
+                        } else {
+                            m_handler.log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Return null, an exception was throwed in the get method", e);
                             return null;
                         }
-
-                        // The nullable class is loaded, create the object and add it
-                        Object instance = nullableClazz.newInstance();
-                        m_usage.getObjects().add(instance);
+                    } catch (InstantiationException e) {
+                        // There is a problem in the dependency resolving (like in stopping
+                        // method)
+                        if (m_isAggregate) {
+                            m_handler.log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Return an empty array, an exception was throwed in the get method", e);
+                            return Array.newInstance(m_clazz, 0);
+                        } else {
+                            m_handler.log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Return null, an exception was throwed in the get method", e);
+                            return null;
+                        }
                     }
-                }
-                m_usage.setStackLevel(1);
-            }
-
-            if (!m_isAggregate) {
-                return m_usage.getObjects().get(0);
-            } else { // Multiple dependency
-                return (Object[]) m_usage.getObjects().toArray((Object[]) Array.newInstance(m_clazz, 0));
-            }
-
-        } catch (Exception e) {
-            // There is a problem in the dependency resolving (like in stopping
-            // method)
-            if (!m_isAggregate) { 
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Return null, an exception was throwed in the get method", e);
-                return null;
-            } else {
-                m_handler.getInstanceManager().getFactory().getLogger().log(
-                        Logger.ERROR,
-                        "[" + m_handler.getInstanceManager().getClassName()
-                                + "] Return an empty array, an exception was throwed in the get method", e);
-                return Array.newInstance(m_clazz, 0);
-            }
-        }
-    }
-
-    /**
-     * Method called when a service event occurs.
-     * 
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     * @param event :
-     *            the received service event
-     */
-    public void serviceChanged(ServiceEvent event) {
-        synchronized (this) {
-
-            // If a service goes way.
-            if (event.getType() == ServiceEvent.UNREGISTERING) {
-                if (m_references.contains(event.getServiceReference())) {
-                    departureManagement(event.getServiceReference());
-                }
-                return;
-            }
-
-            // If a service arrives
-            if (event.getType() == ServiceEvent.REGISTERED) {
-                if (m_filter.match(event.getServiceReference())) {
-                    arrivalManagement(event.getServiceReference());
-                }
-                return;
-            }
-            // If a service is modified
-            if (event.getType() == ServiceEvent.MODIFIED) {
-                if (m_filter.match(event.getServiceReference())) {
-                    if (!m_references.contains(event.getServiceReference())) {
-                        arrivalManagement(event.getServiceReference());
-                    }
+                    m_usage.getObjects().add(instance);
                 } else {
-                    if (m_references.contains(event.getServiceReference())) {
-                        departureManagement(event.getServiceReference());
-                    }
+                    m_usage.getReferences().add(m_tracker.getServiceReference());
+                    m_usage.getObjects().add(getService(m_tracker.getServiceReference()));
                 }
-                return;
             }
-
-        }
-    }
-
-    /**
-     * Method called when a service arrives.
-     * 
-     * @param ref : the arriving service reference
-     */
-    private void arrivalManagement(ServiceReference ref) {
-        m_references.add(ref);
-        if (isSatisfied()) {
-            m_state = RESOLVED;
-            if (m_isAggregate || ! m_references.isEmpty()) {
-                callBindMethod(ref);
-            }
-        }
-        m_handler.checkContext();
-    }
-
-    /**
-     * Method called when a service goes away.
-     * @param ref : the leaving service reference
-     */
-    private void departureManagement(ServiceReference ref) {
-        // Call unbind method
-        boolean hasChanged = false;
-        if (m_usedReferences.contains(ref)) {
-            callUnbindMethod(ref);
-            // Unget the service reference
-            ungetService(ref);
-            m_usedReferences.remove(ref);
-            hasChanged = true;
+            m_usage.setStackLevel(1);
         }
 
-        // Remove from the list.
-        m_references.remove(ref);
-
-        // Is the state valid or invalid
-        if (m_references.isEmpty() && !m_isOptional) {
-            m_state = UNRESOLVED;
+        if (m_isAggregate) { // Multiple dependency
+            return (Object[]) m_usage.getObjects().toArray((Object[]) Array.newInstance(m_clazz, 0));
         } else {
-            m_state = RESOLVED;
+            return m_usage.getObjects().get(0);
         }
-
-        // Is there any change ?
-        if (!m_isAggregate) {
-            if (hasChanged) {
-                if (!m_references.isEmpty()) {
-                    callBindMethod((ServiceReference) m_references.get(0));
-                }
-            }
-        }
-
-        m_handler.checkContext();
-        return;
     }
 
     /**
      * Call unbind callback method.
-     * 
      * @param ref : reference to send (if accepted) to the method
      */
     private void callUnbindMethod(ServiceReference ref) {
-        if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
+        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects().length > 0) {
             for (int i = 0; i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.UNBIND) {
                     try {
                         m_callbacks[i].call(ref, getService(ref));
                     } catch (NoSuchMethodException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class "
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class "
                                         + m_handler.getInstanceManager().getClassName());
                         return;
                     } catch (IllegalAccessException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR,
-                                "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class "
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class "
                                         + m_handler.getInstanceManager().getClassName());
                         return;
                     } catch (InvocationTargetException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR,
-                                "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
                                         + "throws an exception : " + e.getMessage());
                         return;
                     }
@@ -462,7 +369,7 @@
         if (!m_usedReferences.contains(ref)) {
             m_usedReferences.add(ref);
         }
-        return m_serviceContext.getService(ref);
+        return m_tracker.getService(ref);
     }
     
     /**
@@ -475,38 +382,36 @@
 
     /**
      * Call the bind method.
-     * 
      * @param instance : instance on which calling the bind method.
      */
     protected void callBindMethod(Object instance) {
+        if (m_tracker == null) { return; }
         // Check optional case : nullable object case : do not call bind on nullable object
-        if (m_isOptional && m_references.isEmpty()) {
+        if (m_isOptional && m_tracker.size() == 0) {
             return;
         }
 
         if (m_isAggregate) {
-            for (int i = 0; i < m_references.size(); i++) {
-                for (int j = 0; j < m_callbacks.length; j++) {
-                    if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
-                        try {
-                            m_callbacks[j].callOnInstance(instance, (ServiceReference) m_references.get(i), getService((ServiceReference) m_references.get(i)));
-                        } catch (NoSuchMethodException e) {
-                            m_handler.getInstanceManager().getFactory().getLogger().log(
-                                    Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class "
-                                            + m_handler.getInstanceManager().getClassName());
-                            return;
-                        } catch (IllegalAccessException e) {
-                            m_handler.getInstanceManager().getFactory().getLogger().log(
-                                    Logger.ERROR,
-                                    "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class "
-                                            + m_handler.getInstanceManager().getClassName());
-                            return;
-                        } catch (InvocationTargetException e) {
-                            m_handler.getInstanceManager().getFactory().getLogger().log(
-                                    Logger.ERROR,
-                                    "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
-                                            + "thorws an exception : " + e.getMessage());
-                            return;
+            synchronized (m_tracker) {
+                ServiceReference[] refs = m_tracker.getServiceReferences();
+                for (int i = 0; i < refs.length; i++) {
+                    for (int j = 0; j < m_callbacks.length; j++) {
+                        if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
+                            try {
+                                m_callbacks[j].callOnInstance(instance, refs[i], getService(refs[i]));
+                            } catch (NoSuchMethodException e) {
+                                m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class "
+                                                + m_handler.getInstanceManager().getClassName());
+                                return;
+                            } catch (IllegalAccessException e) {
+                                m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class "
+                                                + m_handler.getInstanceManager().getClassName());
+                                return;
+                            } catch (InvocationTargetException e) {
+                                m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
+                                                + "thorws an exception : " + e.getMessage());
+                                return;
+                            }
                         }
                     }
                 }
@@ -515,23 +420,19 @@
             for (int j = 0; j < m_callbacks.length; j++) {
                 if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
                     try {
-                        m_callbacks[j].callOnInstance(instance, (ServiceReference) m_references.get(0), getService((ServiceReference) m_references.get(0)));
+                        ServiceReference ref = m_tracker.getServiceReference();
+                        m_callbacks[j].callOnInstance(instance, ref, getService(ref));
                     } catch (NoSuchMethodException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class "
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class "
                                         + m_handler.getInstanceManager().getClassName());
                         return;
                     } catch (IllegalAccessException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR,
-                                "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class "
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class "
                                         + m_handler.getInstanceManager().getClassName());
                         return;
                     } catch (InvocationTargetException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR,
-                                "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
-                                        + "thorws an exception : " + e.getMessage());
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
+                                        + "throws an exception : " + e.getMessage());
                         return;
                     }
                 }
@@ -541,31 +442,26 @@
 
     /**
      * Call bind method with the service reference in parameter (if accepted).
-     * 
      * @param ref : the service reference of the new service
      */
     private void callBindMethod(ServiceReference ref) {
         // call bind method :
-        if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
+       // if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
+        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects().length > 0) {
             for (int i = 0; i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.BIND) {
                     try {
                         m_callbacks[i].call(ref, getService(ref));
                     } catch (NoSuchMethodException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class "
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class "
                                         + m_handler.getInstanceManager().getClassName());
                         return;
                     } catch (IllegalAccessException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR,
-                                "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class "
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class "
                                         + m_handler.getInstanceManager().getClassName());
                         return;
                     } catch (InvocationTargetException e) {
-                        m_handler.getInstanceManager().getFactory().getLogger().log(
-                                Logger.ERROR,
-                                "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
+                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
                                         + "throws an exception : " + e.getMessage());
                         return;
                     }
@@ -584,70 +480,47 @@
         // Construct the filter with the objectclass + filter
         String classnamefilter = "(objectClass=" + m_specification + ")";
         String filter = "";
-        if (!m_strFilter.equals("")) {
-            filter = "(&" + classnamefilter + m_strFilter + ")";
-        } else {
+        if ("".equals(m_strFilter)) {
             filter = classnamefilter;
+        } else {
+            filter = "(&" + classnamefilter + m_strFilter + ")";
         }
 
-        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO,
-                "[" + m_handler.getInstanceManager().getClassName() + "] Start a dependency on : " + m_specification + " with " + m_strFilter);
         m_state = UNRESOLVED;
 
         try {
             m_clazz = m_handler.getInstanceManager().getContext().getBundle().loadClass(m_specification);
         } catch (ClassNotFoundException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "Cannot load the interface class for the dependency " + m_field + " [" + m_specification + "]");
+            m_handler.log(Logger.ERROR, "Cannot load the interface class for the dependency " + m_field + " [" + m_specification + "]");
+            return;
         }
 
         try {
-            // Look if the service is already present :
-            if (lookForServiceReferences(m_specification, filter)) {
-                m_state = RESOLVED;
-            }
-            // Register a listener :
-            m_serviceContext.addServiceListener(this);
-         
             m_filter = m_handler.getInstanceManager().getContext().createFilter(filter); // Store the filter
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Create a filter from : " + filter);
         } catch (InvalidSyntaxException e1) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "[" + m_handler.getInstanceManager().getClassName() + "] A filter is malformed : " + filter + " - " + e1.getMessage());
+            m_handler.log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] A filter is malformed : " + filter + " - " + e1.getMessage());
+            return;
         }
-    }
-
-    /**
-     * Look for available service.
-     * @param specification : required specification.
-     * @param filter : LDAP Filter
-     * @return true if at least one service is found.
-     */
-    private boolean lookForServiceReferences(String specification, String filter) {
-        boolean success = false; // Are the query fulfilled ?
-        try {
-            ServiceReference[] refs = m_serviceContext.getServiceReferences(specification, filter);
-            if (refs != null) {
-                success = true;
-                for (int i = 0; i < refs.length; i++) {
-                    m_references.add(refs[i]);
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "The requirement on " + m_specification + " does not have a vlid filter : " + e.getMessage());
+        
+        m_tracker = new Tracker(m_serviceContext, m_filter, this);
+        m_tracker.open();
+        if (m_tracker.size() == 0 && !m_isOptional) {
+            m_state = UNRESOLVED;
+        } else {
+            m_state = RESOLVED;
         }
-        return success;
     }
 
     /**
      * Stop the dependency.
      */
     public void stop() {
-        m_serviceContext.removeServiceListener(this);
+        if (m_tracker != null) {
+            m_tracker.close();
+            m_tracker = null;
+        }
         
-        m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO,
-                "[" + m_handler.getInstanceManager().getInstanceName() + "] Stop a dependency on : " + m_specification + " with " + m_strFilter + " (" + m_handler.getInstanceManager() + ")");
+        m_handler.log(Logger.INFO, "[" + m_handler.getInstanceManager().getInstanceName() + "] Stop a dependency on : " + m_specification + " with " + m_strFilter + " (" + m_handler.getInstanceManager() + ")");
         m_state = UNRESOLVED;
 
         // Unget all services references
@@ -655,7 +528,6 @@
             ungetService((ServiceReference) m_usedReferences.get(i));
         }
 
-        m_references.clear();
         m_usedReferences.clear();
         m_clazz = null;
     }
@@ -679,9 +551,11 @@
      * @return the service reference list.
      */
     public List getServiceReferences() {
-        List refs = new ArrayList();
-        refs.addAll(m_references);
-        return refs;
+        if (m_tracker.size() != 0) {
+            return m_tracker.getServiceReferencesList();
+        } else {
+            return new ArrayList();
+        }
     }
     
     protected DependencyCallback[] getCallbacks() {
@@ -734,4 +608,68 @@
         }
     }
 
+   /**
+    * A new service is detected. This method check the reference against the stored filter.
+    * @param ref : new service reference.
+    * @return the service object, null is the service object is rejected.
+    * @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+    */
+    public boolean addingService(ServiceReference ref) {
+        if (m_filter.match(ref)) {
+            m_state = RESOLVED;
+            if (m_isAggregate || m_tracker.size() == 0) {
+                callBindMethod(ref);
+            }
+            
+            m_handler.checkContext();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * A used service is modified.
+     * @param ref : modified reference
+     * @param arg1 : service object (returned when added) 
+     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference ref, Object arg1) { }
+
+    /**
+     * A used service disappears.
+     * @param ref : implicated service.
+     * @param arg1 : service object.
+     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference ref, Object arg1) {
+        // Call unbind method
+        boolean hasChanged = false;
+        if (m_usedReferences.contains(ref)) {
+            callUnbindMethod(ref);
+            // Unget the service reference
+            ungetService(ref);
+            m_usedReferences.remove(ref);
+            hasChanged = true;
+        }
+
+        // Is the state valid or invalid, the reference is already removed
+        if (m_tracker.size() == 0 && !m_isOptional) {
+            m_state = UNRESOLVED;
+        } else {
+            m_state = RESOLVED;
+        }
+
+        // Is there any change ?
+        if (!m_isAggregate) {
+            if (hasChanged) { // The used reference has been removed
+                if (m_tracker.size() != 0) {
+                    callBindMethod(m_tracker.getServiceReference());
+                }
+            }
+        }
+
+        m_handler.checkContext();
+        return;
+    }
+
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
index 4e3c8f9..fe5f033 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
@@ -97,7 +97,7 @@
      */
     public void setArgument(String arg) {
         m_argument = arg;
-        if (arg.equals("EMPTY")) {
+        if ("EMPTY".equals(arg)) {
             m_callback = new Callback(m_method, new String[0], false, m_manager);
         } else {
             m_callback = new Callback(m_method, new String[] {arg}, false, m_manager);
@@ -130,7 +130,7 @@
      * @throws IllegalAccessException : The method can not be invoked
      */
     protected void call(ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        if (m_argument.equals("EMPTY")) {
+        if ("EMPTY".equals(m_argument)) {
             m_callback.call(new Object[] {});
         } else {
             if (m_argument.equals(ServiceReference.class.getName())) {
@@ -153,7 +153,7 @@
      * @throws InvocationTargetException
      */
     protected void callOnInstance(Object instance, ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        if (m_argument.equals("EMPTY")) {
+        if ("EMPTY".equals(m_argument)) {
             m_callback.call(instance, new Object[] {});
             return;
         }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
index 7c7f2a3..206734f 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -23,9 +23,9 @@
 import java.util.Dictionary;
 import java.util.List;
 
-import org.apache.felix.ipojo.Handler;
-import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.handlers.dependency.nullable.NullableObjectWriter;
 import org.apache.felix.ipojo.metadata.Element;
@@ -36,19 +36,13 @@
 import org.osgi.framework.ServiceReference;
 
 /**
- * The dependency handler manages a list of dependencies.
- * 
+ * The dependency handler manages a list of service dependencies.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class DependencyHandler extends Handler {
+public class DependencyHandler extends PrimitiveHandler {
 
     /**
-     * The instance manager using this handler.
-     */
-    private InstanceManager m_manager;
-
-    /**
-     * List of depednencies of the component.
+     * List of dependencies of the component.
      */
     private Dependency[] m_dependencies = new Dependency[0];
 
@@ -59,10 +53,9 @@
 
     /**
      * State of the handler.
+     * Lifecycle controller.
      */
-    private int m_state;
-
-    // ===================== Fields getters & setters =====================
+    private boolean m_state;
 
     /**
      * Add a dependency.
@@ -71,9 +64,7 @@
      */
     private void addDependency(Dependency dep) {
         for (int i = 0; (m_dependencies != null) && (i < m_dependencies.length); i++) {
-            if (m_dependencies[i] == dep) {
-                return;
-            }
+            if (m_dependencies[i] == dep) { return; }
         }
         if (m_dependencies.length > 0) {
             Dependency[] newDep = new Dependency[m_dependencies.length + 1];
@@ -92,9 +83,7 @@
      */
     private void addNullableClass(Class clazz) {
         for (int i = 0; (m_nullableClasses != null) && (i < m_nullableClasses.length); i++) {
-            if (m_nullableClasses[i] == clazz) {
-                return;
-            }
+            if (m_nullableClasses[i] == clazz) { return; }
         }
         if (m_nullableClasses.length > 0) {
             Class[] newClass = new Class[m_nullableClasses.length + 1];
@@ -115,38 +104,26 @@
     }
 
     /**
-     * Get the instance manager.
-     * @return the instance manager
-     */
-    protected InstanceManager getInstanceManager() {
-        return m_manager;
-    }
-
-    // ===================== Handler implementation =====================
-
-    /**
      * Check the validity of the dependencies.
      */
     protected void checkContext() {
-        synchronized (this) {
+        synchronized (m_dependencies) {
             // Store the initial state
-            int initialState = m_state;
+            boolean initialState = m_state;
 
             // Check the component dependencies
             if (validateComponentDependencies()) {
                 // The dependencies are valid
-                if (initialState == InstanceManager.INVALID) {
+                if (!initialState) {
                     // There is a state change
-                    m_state = InstanceManager.VALID;
-                    m_manager.checkInstanceState();
+                    m_state = true;
                 }
                 // Else do nothing, the component state stay VALID
             } else {
                 // The dependencies are not valid
-                if (initialState == InstanceManager.VALID) {
+                if (initialState) {
                     // There is a state change
-                    m_state = InstanceManager.INVALID;
-                    m_manager.checkInstanceState();
+                    m_state = false;
                 }
                 // Else do nothing, the component state stay UNRESOLVED
             }
@@ -157,25 +134,25 @@
     /**
      * Check if the dependency given is valid in the sense that metadata are
      * consistent.
-     * 
      * @param dep : the dependency to check
      * @param manipulation : the component-type manipulation metadata
      * @return true if the dependency is valid
+     * @throws ConfigurationException : the checked dependency is not correct
      */
-    private boolean checkDependency(Dependency dep, ManipulationMetadata manipulation) {
+    private boolean checkDependency(Dependency dep, ManipulationMetadata manipulation) throws ConfigurationException {
         // Check the internal type of dependency
         String field = dep.getField();
         DependencyCallback[] callbacks = dep.getCallbacks();
-        
+
         for (int i = 0; i < callbacks.length; i++) {
             MethodMetadata[] mets = manipulation.getMethods(callbacks[i].getMethodName());
             if (mets.length == 0) {
-                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A dependency callback " + callbacks[i].getMethodName() + " does not exist in the implementation");
-                return false;
+                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation");
+                throw new ConfigurationException("Requirement Callback : A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation", getInstanceManager().getFactory().getName());
             }
             if (mets[0].getMethodArguments().length > 1) {
-                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A dependency callback " + callbacks[i].getMethodName() + " must have 0 or 1 argument");
-                return false;
+                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 argument");
+                throw new ConfigurationException("Requirement Callback : A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 argument", getInstanceManager().getFactory().getName());
             }
             if (mets[0].getMethodArguments().length == 0) {
                 callbacks[i].setArgument("EMPTY");
@@ -186,68 +163,67 @@
                         dep.setSpecification(mets[0].getMethodArguments()[0]);
                     }
                     if (!dep.getSpecification().equals(mets[0].getMethodArguments()[0])) {
-                        m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The field type [" + mets[0].getMethodArguments()[0] + "] and the needed service interface ["
-                                    + dep.getSpecification() + "] are not the same");
+                        log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + mets[0].getMethodArguments()[0] + "] and the needed service interface [" + dep.getSpecification()
+                                + "] are not the same");
                         dep.setSpecification(mets[0].getMethodArguments()[0]);
                     }
                 }
-            }   
+            }
         }
-        
+
         if (field != null) {
             FieldMetadata fm = manipulation.getField(field);
             if (fm == null) {
-                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A dependency field " + field + " does not exist in the implementation class");
-                return false;
+                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A requirement field " + field + " does not exist in the implementation class");
+                throw new ConfigurationException("Requirement Callback : A requirement field " + field + " does not exist in the implementation class", getInstanceManager().getFactory().getName());
             }
-            String type = fm.getFieldType(); 
+            String type = fm.getFieldType();
             if (type.endsWith("[]")) {
                 // Set the dependency to multiple
                 dep.setAggregate();
                 type = type.substring(0, type.length() - 2);
             }
 
-            if (dep.getSpecification() == null) { dep.setSpecification(type); }
+            if (dep.getSpecification() == null) {
+                dep.setSpecification(type);
+            }
 
             if (!dep.getSpecification().equals(type)) {
-                m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The field type [" + type + "] and the needed service interface ["
-                                + dep.getSpecification() + "] are not the same");
+                log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + type + "] and the needed service interface [" + dep.getSpecification() + "] are not the same");
                 dep.setSpecification(type);
             }
         }
-        
+
         //Check that all required info are set
         return dep.getSpecification() != null;
     }
 
     /**
      * Configure the handler.
-     * @param im : the instance manager
      * @param componentMetadata : the component type metadata
      * @param configuration : the instance configuration
+     * @throws ConfigurationException : one dependency metadata is not correct.
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(InstanceManager im, Element componentMetadata, Dictionary configuration) {
-        m_manager = im;
+    public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
         m_dependencies = new Dependency[0];
         m_nullableClasses = new Class[0];
-        
+
         ManipulationMetadata manipulation = new ManipulationMetadata(componentMetadata);
         List fl = new ArrayList();
 
         // Create the dependency according to the component metadata
-        Element[] deps = componentMetadata.getElements("Requires"); 
-        
+        Element[] deps = componentMetadata.getElements("Requires");
+
         // DEPRECATED BLOCK :
         if (deps.length == 0) {
             deps = componentMetadata.getElements("Dependency");
             if (deps.length != 0) {
-                im.getFactory().getLogger().log(Logger.WARNING, "Dependency is deprecated, please use 'requires' instead of 'dependency'");
+                log(Logger.WARNING, "Dependency is deprecated, please use 'requires' instead of 'dependency'");
             }
         }
         // END OF DEPRECATED BLOCK
 
-         
         for (int i = 0; i < deps.length; i++) {
             // Create the dependency metadata
             String field = null;
@@ -263,19 +239,19 @@
                 filter = deps[i].getAttribute("filter");
             }
             boolean optional = false;
-            if (deps[i].containsAttribute("optional") && deps[i].getAttribute("optional").equals("true")) {
+            if (deps[i].containsAttribute("optional") && "true".equals(deps[i].getAttribute("optional"))) {
                 optional = true;
             }
             boolean aggregate = false;
-            if (deps[i].containsAttribute("aggregate") && deps[i].getAttribute("aggregate").equals("true")) {
+            if (deps[i].containsAttribute("aggregate") && "true".equals(deps[i].getAttribute("aggregate"))) {
                 aggregate = true;
             }
-            
+
             String id = null;
             if (deps[i].containsAttribute("id")) {
                 id = deps[i].getAttribute("id");
             }
-            
+
             int scopePolicy = -1;
             if (deps[i].containsAttribute("scope")) {
                 if (deps[i].getAttribute("scope").equalsIgnoreCase("global")) {
@@ -284,17 +260,20 @@
                     scopePolicy = PolicyServiceContext.LOCAL;
                 } else if (deps[i].getAttribute("scope").equalsIgnoreCase("composite+global")) {
                     scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
-                }                
+                }
             }
 
             Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate, id, scopePolicy);
-            
+
             // Look for dependency callback :
             for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
+                if (!(deps[i].getElements("Callback", "")[j].containsAttribute("method") && deps[i].getElements("Callback", "")[j].containsAttribute("type"))) { 
+                    throw new ConfigurationException("Requirement Callback : a dependency callback must contain a method and a type attribute", getInstanceManager().getFactory().getName()); 
+                }
                 String method = deps[i].getElements("Callback", "")[j].getAttribute("method");
                 String type = deps[i].getElements("Callback", "")[j].getAttribute("type");
                 int methodType = 0;
-                if (type.equals("bind")) {
+                if ("bind".equalsIgnoreCase(type)) {
                     methodType = DependencyCallback.BIND;
                 } else {
                     methodType = DependencyCallback.UNBIND;
@@ -303,7 +282,7 @@
                 DependencyCallback dc = new DependencyCallback(dep, method, methodType);
                 dep.addDependencyCallback(dc);
             }
-            
+
             // Check the dependency :
             if (checkDependency(dep, manipulation)) {
                 addDependency(dep);
@@ -311,14 +290,13 @@
                     fl.add(manipulation.getField(dep.getField()));
                 }
             } else {
-                m_manager.getFactory().getLogger().log(Logger.ERROR,
-                        "[DependencyHandler on " + m_manager.getClassName() + "] The dependency on " + dep.getField() + " is not valid");
+                log(Logger.ERROR, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The dependency on " + dep.getField() + " is not valid");
             }
 
         }
 
         if (deps.length > 0) {
-            m_manager.register(this, (FieldMetadata[]) fl.toArray(new FieldMetadata[0]), manipulation.getMethods());
+            getInstanceManager().register(this, (FieldMetadata[]) fl.toArray(new FieldMetadata[0]), manipulation.getMethods());
         }
     }
 
@@ -328,8 +306,7 @@
      * @param dep : the dependency
      */
     private void createNullableClass(Dependency dep) {
-        m_manager.getFactory().getLogger().log(Logger.INFO,
-                "[DependencyHandler on " + m_manager.getClassName() + "] Try to load the nullable class for " + dep.getSpecification());
+        log(Logger.INFO, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] Try to load the nullable class for " + dep.getSpecification());
 
         // String[] segment =
         // dep.getMetadata().getServiceSpecification().split("[.]");
@@ -337,23 +314,22 @@
         // - 1] + "Nullable";
         String className = dep.getSpecification() + "Nullable";
         String resource = dep.getSpecification().replace('.', '/') + ".class";
-        URL url = m_manager.getContext().getBundle().getResource(resource);
+        URL url = getInstanceManager().getContext().getBundle().getResource(resource);
 
         try {
             byte[] b = NullableObjectWriter.dump(url, dep.getSpecification());
             Class c = null;
             try {
-                c = m_manager.getFactory().defineClass(className, b, null);
+                c = getInstanceManager().getFactory().defineClass(className, b, null);
             } catch (Exception e) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "Cannot define the nullable class : " + e.getMessage());
+                log(Logger.ERROR, "Cannot define the nullable class : " + e.getMessage());
+                e.printStackTrace();
                 return;
             }
             addNullableClass(c);
-            m_manager.getFactory().getLogger().log(Logger.INFO,
-                    "[DependencyHandler on " + m_manager.getClassName() + "] Nullable class created for " + dep.getSpecification());
+            log(Logger.INFO, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] Nullable class created for " + dep.getSpecification());
         } catch (Exception e2) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR,
-                    "[DependencyHandler on " + m_manager.getClassName() + "] Cannot load the nullable class for  " + dep.getSpecification(), e2);
+            log(Logger.ERROR, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] Cannot load the nullable class for  " + dep.getSpecification(), e2);
         }
     }
 
@@ -367,9 +343,7 @@
     protected Class getNullableClass(String name) {
         for (int i = 0; i < m_nullableClasses.length; i++) {
             Class c = m_nullableClasses[i];
-            if (c.getName().equals(name)) {
-                return c;
-            }
+            if (c.getName().equals(name)) { return c; }
         }
         return null;
     }
@@ -392,7 +366,7 @@
         // Else return the value
         return value;
     }
-    
+
     /**
      * Method Entry callback.
      * @param methodId : method Id.
@@ -404,7 +378,7 @@
             dep.entry(methodId);
         }
     }
-    
+
     /**
      * Method Exit callback.
      * @param methodId : method id.
@@ -417,25 +391,12 @@
             dep.exit(methodId);
         }
     }
-    
-    
-
-    /**
-     * Check the handler validity.
-     * @return true if all mandatory dependencies are resolved.
-     * @see org.apache.felix.ipojo.Handler#isValid()
-     */
-    public boolean isValid() {
-        return m_state == InstanceManager.VALID;
-    }
 
     /**
      * Handler start method.
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-        m_manager.getFactory().getLogger().log(Logger.INFO, "[DependencyHandler on " + m_manager.getClassName() + "] Start the dependency handler");
-
         // Start the dependencies, for optional dependencies create Nullable
         // class
         for (int i = 0; i < m_dependencies.length; i++) {
@@ -446,20 +407,10 @@
             dep.start();
         }
         // Check the state
-        m_state = m_manager.getState();
         checkContext();
     }
 
     /**
-     * Handler stateChanged method.
-     * @param state : new instance state
-     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
-     */
-    public void stateChanged(int state) {
-        m_state = state;
-    }
-
-    /**
      * Handler stop method.
      * @see org.apache.felix.ipojo.Handler#stop()
      */
@@ -474,9 +425,9 @@
      * Handler createInstance method.
      * This method is overided to allow delayed callback invocation.
      * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#createInstance(java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
      */
-    public void createInstance(Object instance) {
+    public void objectCreated(Object instance) {
         for (int i = 0; i < m_dependencies.length; i++) {
             m_dependencies[i].callBindMethod(instance);
         }
@@ -490,10 +441,8 @@
         boolean valide = true;
         for (int i = 0; i < m_dependencies.length; i++) {
             Dependency dep = m_dependencies[i];
-            valide = valide & dep.isSatisfied();
-            if (!valide) {
-                return false;
-            }
+            valide = valide & dep.getState() == Dependency.RESOLVED;
+            if (!valide) { return false; }
         }
         return valide;
     }
@@ -504,7 +453,7 @@
      * @see org.apache.felix.ipojo.Handler#getDescription()
      */
     public HandlerDescription getDescription() {
-        DependencyHandlerDescription dhd = new DependencyHandlerDescription(isValid());
+        DependencyHandlerDescription dhd = new DependencyHandlerDescription(this);
         for (int j = 0; j < getDependencies().length; j++) {
             Dependency dep = getDependencies()[j];
             // Create & add the dependency description
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
index f3905da..225b215 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
@@ -21,10 +21,10 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.felix.ipojo.Handler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
-import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -41,11 +41,10 @@
 
     /**
      * Constructor.
-     * 
-     * @param isValid : the validity of the dependency handler.
+     * @param h : Handler.
      */
-    public DependencyHandlerDescription(boolean isValid) {
-        super(DependencyHandler.class.getName(), isValid);
+    public DependencyHandlerDescription(Handler h) {
+        super(h);
     }
 
     /**
@@ -91,7 +90,7 @@
             Element dep = new Element("Requires", "");
             dep.addAttribute(new Attribute("Specification", m_dependencies[i].getInterface()));
             
-            if (!m_dependencies[i].getFilter().equals("")) {
+            if (!"".equals(m_dependencies[i].getFilter())) {
                 dep.addAttribute(new Attribute("Filter", m_dependencies[i].getFilter()));
             }
             
@@ -113,10 +112,10 @@
             while (it.hasNext()) {
                 Element use = new Element("Uses", "");
                 ServiceReference ref = (ServiceReference) it.next();
-                use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString()));
-                String pid = (String) ref.getProperty(Constants.SERVICE_PID);
-                if (pid != null) {
-                    use.addAttribute(new Attribute("service.pid", pid));
+                use.addAttribute(new Attribute("instance.name", ref.getProperty("instance.name").toString()));
+                String in = (String) ref.getProperty("instance.name");
+                if (in != null) {
+                    use.addAttribute(new Attribute("instance.name", in));
                 }
                 dep.addElement(use);
             }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
index c92ae63..15db443 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
@@ -41,7 +41,7 @@
     protected static final int INVALIDATE = 0;
     
     /**
-     * Transition on wich calling the callback.
+     * Transition on which calling the callback.
      */
     private int m_transition;
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
index d4b431d..bec6709 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
@@ -22,8 +22,9 @@
 import java.util.Dictionary;
 
 import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
@@ -34,7 +35,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class LifecycleCallbackHandler extends Handler {
+public class LifecycleCallbackHandler extends PrimitiveHandler {
 
     /**
      * The list of the callback of the component.
@@ -45,12 +46,6 @@
      * State of the instance manager (unresolved at the beginning).
      */
     private int m_state = InstanceManager.INVALID;
-
-    /**
-     * The instance manager.
-     */
-    private InstanceManager m_manager;
-
     /**
      * Does a POJO object be created at starting.
      */
@@ -81,13 +76,12 @@
 
     /**
      * Configure the handler.
-     * @param cm : the instance manager
      * @param metadata : the component type metadata
      * @param configuration : the instance configuration
+     * @throws ConfigurationException : one callback metadata is not correct (either the transition or the method are not correct).
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(InstanceManager cm, Element metadata, Dictionary configuration) {
-        m_manager = cm;
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
         m_callbacks = new LifecycleCallback[0];
 
         if (metadata.containsAttribute("immediate") && metadata.getAttribute("immediate").equalsIgnoreCase("true")) {
@@ -98,6 +92,9 @@
 
         Element[] hooksMetadata = metadata.getElements("callback");
         for (int i = 0; i < hooksMetadata.length; i++) {
+            if (! hooksMetadata[i].containsAttribute("method")) {
+                throw new ConfigurationException("Lifecycle callback : A callback needs to contains a method attribute", getInstanceManager().getFactory().getName());
+            }
             String methodName = hooksMetadata[i].getAttribute("method");
             
             MethodMetadata met = mm.getMethod(methodName, new String[0]);
@@ -114,7 +111,7 @@
             
             //DEPRECATED BLOCK
             if (hooksMetadata[i].containsAttribute("initial")) {
-                cm.getFactory().getLogger().log(Logger.WARNING, "initial & final are deprecated, please use 'transition=validate|invalidate' instead.");
+                log(Logger.WARNING, "initial & final are deprecated, please use 'transition=validate|invalidate' instead.");
                 if (hooksMetadata[i].containsAttribute("final")) {
                     if (hooksMetadata[i].getAttribute("initial").equalsIgnoreCase("valid") && hooksMetadata[i].getAttribute("final").equalsIgnoreCase("invalid")) {
                         transition = LifecycleCallback.INVALIDATE;
@@ -126,8 +123,8 @@
             //END OF DEPRECATED BLOCK
             
             if (transition == -1) {
-                cm.getFactory().getLogger().log(Logger.ERROR, "Unknown or malformed transition");
-                return;
+                log(Logger.ERROR, "Unknown or malformed transition");
+                throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition", getInstanceManager().getFactory().getName());
             }
             
             LifecycleCallback hk = null;
@@ -138,9 +135,6 @@
             }
             addCallback(hk);
         }
-        if (m_callbacks.length > 0 || m_immediate) {
-            m_manager.register(this);
-        }
     }
 
     /**
@@ -159,14 +153,6 @@
     }
 
     /**
-     * Get the instance manager.
-     * @return the instance manager
-     */
-    protected InstanceManager getInstanceManager() {
-        return m_manager;
-    }
-
-    /**
      * When the state change call the associated callback.
      * 
      * @param state : the new instance state.
@@ -182,8 +168,8 @@
         }
         
         // Manage immediate component
-        if (m_immediate && transition == LifecycleCallback.VALIDATE && m_manager.getPojoObjects().length == 0) {
-            m_manager.createPojoObject();
+        if (m_immediate && transition == LifecycleCallback.VALIDATE && getInstanceManager().getPojoObjects().length == 0) {
+            getInstanceManager().getPojoObject();
         }
 
         for (int i = 0; i < m_callbacks.length; i++) {
@@ -191,15 +177,15 @@
                 try {
                     m_callbacks[i].call();
                 } catch (NoSuchMethodException e) {
-                    m_manager.getFactory().getLogger().log(Logger.ERROR,
-                            "[" + m_manager.getClassName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found", e);
+                    log(Logger.ERROR,
+                            "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found", e);
                 } catch (IllegalAccessException e) {
-                    m_manager.getFactory().getLogger().log(Logger.ERROR,
-                            "[" + m_manager.getClassName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible", e);
+                    log(Logger.ERROR,
+                            "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible", e);
                 } catch (InvocationTargetException e) {
-                    m_manager.getFactory().getLogger().log(
+                    log(
                             Logger.ERROR,
-                            "[" + m_manager.getClassName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : "
+                            "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : "
                                     + e.getMessage());
                 }
             }
@@ -207,5 +193,4 @@
         // Update to internal state
         m_state = state;
     }
-
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
index 385f77c..03f9eee 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
@@ -20,8 +20,10 @@
 

 import java.util.Dictionary;

 

-import org.apache.felix.ipojo.Handler;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.ConfigurationException;

 import org.apache.felix.ipojo.InstanceManager;

+import org.apache.felix.ipojo.PrimitiveHandler;

 import org.apache.felix.ipojo.metadata.Element;

 import org.apache.felix.ipojo.parser.FieldMetadata;

 import org.apache.felix.ipojo.parser.ManipulationMetadata;

@@ -32,12 +34,7 @@
  * This handler allow a POJO  to vote for the instance state. By setting a boolean field to true or false, the handler state changed.

  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

  */

-public class ControllerHandler extends Handler {

-    

-    /**

-     * Instance Manager.

-     */

-    private InstanceManager m_manager;

+public class ControllerHandler extends PrimitiveHandler {

     

     /**

      * Actual handler (i.e. field value) state

@@ -47,13 +44,12 @@
     /**

      * Configure method.

      * Look for the first 'controller' element.

-     * @param im : instance manager

      * @param metadata : metadata

      * @param configuration : configuration

+     * @throws ConfigurationException : the field attribute is missing or does not exist in the class.

      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

      */

-    public void configure(InstanceManager im, Element metadata, Dictionary configuration) {

-        m_manager = im;

+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {

         String field = null;

         Element[] lc = metadata.getElements("controller");

         if (lc.length > 0) {

@@ -61,8 +57,8 @@
             if (lc[0].containsAttribute("field")) {

                 field = lc[0].getAttribute("field");

             } else {

-                m_manager.getFactory().getLogger().log(Logger.ERROR, "A lifecycle controler needs to contain a field attribute");

-                return;

+                log(Logger.ERROR, "A lifecycle controler needs to contain a field attribute");

+                throw new ConfigurationException("Lifecycle controller : the controller element needs to have a field attribute", getInstanceManager().getFactory().getName());

             }

         } else {

             return;

@@ -71,16 +67,16 @@
         ManipulationMetadata mm = new ManipulationMetadata(metadata);

         FieldMetadata fm = mm.getField(field);

         if (fm == null) {

-            m_manager.getFactory().getLogger().log(Logger.ERROR, "The field " + field + " does not exist in the class");

-            return;

+            log(Logger.ERROR, "The field " + field + " does not exist in the class");

+            throw new ConfigurationException("Lifecycle controller : The field " + field + " does not exist in the class", getInstanceManager().getFactory().getName());

         }

         

         if (!fm.getFieldType().equalsIgnoreCase("boolean")) {

-            m_manager.getFactory().getLogger().log(Logger.ERROR, "The field " + field + " must be a boolean (" + fm.getFieldType() + " found)");

-            return;

+            log(Logger.ERROR, "The field " + field + " must be a boolean (" + fm.getFieldType() + " found)");

+            throw new ConfigurationException("Lifecycle controller : The field " + field + " must be a boolean (" + fm.getFieldType() + " found)", getInstanceManager().getFactory().getName());

         }

         

-        im.register(this, new FieldMetadata[] {fm}, null);

+        getInstanceManager().register(this, new FieldMetadata[] {fm}, null);

     }

 

     /**

@@ -100,15 +96,6 @@
     public void stop() { }

     

     /**

-     * Return the field value.

-     * @return the field value (i.e. the handler state)

-     * @see org.apache.felix.ipojo.Handler#isValid()

-     */

-    public boolean isValid() {

-        return m_state;

-    }

-    

-    /**

      * GetterCallback.

      * Return the stored value.

      * @param field : field name.

@@ -130,10 +117,14 @@
             boolean nv = ((Boolean) o).booleanValue();

             if (nv != m_state) {

                 m_state = nv;

-                m_manager.checkInstanceState();

+                if (m_state) {

+                    ((InstanceManager) getInstance()).setState(ComponentInstance.VALID);

+                } else {

+                    ((InstanceManager) getInstance()).setState(ComponentInstance.INVALID);

+                }

             }

         } else {

-            m_manager.getFactory().getLogger().log(Logger.ERROR, "Boolean expected");

+            log(Logger.ERROR, "Boolean expected");

         }

     }

 

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
index b916171..fa46d2e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
@@ -178,35 +178,35 @@
         }
 
         // Simple :
-        if (m_type.equals("string") || m_type.equals("String")) {
+        if ("string".equals(m_type) || "String".equals(m_type)) {
             m_value = new String(value);
             return;
         }
-        if (m_type.equals("boolean")) {
+        if ("boolean".equals(m_type)) {
             m_value = new Boolean(value);
             return;
         }
-        if (m_type.equals("byte")) {
+        if ("byte".equals(m_type)) {
             m_value = new Byte(value);
             return;
         }
-        if (m_type.equals("short")) {
+        if ("short".equals(m_type)) {
             m_value = new Short(value);
             return;
         }
-        if (m_type.equals("int")) {
+        if ("int".equals(m_type)) {
             m_value = new Integer(value);
             return;
         }
-        if (m_type.equals("long")) {
+        if ("long".equals(m_type)) {
             m_value = new Long(value);
             return;
         }
-        if (m_type.equals("float")) {
+        if ("float".equals(m_type)) {
             m_value = new Float(value);
             return;
         }
-        if (m_type.equals("double")) {
+        if ("double".equals(m_type)) {
             m_value = new Double(value);
             return;
         }
@@ -243,11 +243,11 @@
      * @param values : the new value
      */
     private void setArrayValue(String internalType, String[] values) {
-        if (internalType.equals("string") || internalType.equals("String")) {
+        if ("string".equals(internalType) || "String".equals(internalType)) {
             m_value = values;
             return;
         }
-        if (internalType.equals("boolean")) {
+        if ("boolean".equals(internalType)) {
             boolean[] bool = new boolean[values.length];
             for (int i = 0; i < values.length; i++) {
                 bool[i] = new Boolean(values[i]).booleanValue();
@@ -255,7 +255,7 @@
             m_value = bool;
             return;
         }
-        if (internalType.equals("byte")) {
+        if ("byte".equals(internalType)) {
             byte[] byt = new byte[values.length];
             for (int i = 0; i < values.length; i++) {
                 byt[i] = new Byte(values[i]).byteValue();
@@ -263,7 +263,7 @@
             m_value = byt;
             return;
         }
-        if (internalType.equals("short")) {
+        if ("short".equals(internalType)) {
             short[] shor = new short[values.length];
             for (int i = 0; i < values.length; i++) {
                 shor[i] = new Short(values[i]).shortValue();
@@ -271,7 +271,7 @@
             m_value = shor;
             return;
         }
-        if (internalType.equals("int")) {
+        if ("int".equals(internalType)) {
             int[] in = new int[values.length];
             for (int i = 0; i < values.length; i++) {
                 in[i] = new Integer(values[i]).intValue();
@@ -279,7 +279,7 @@
             m_value = in;
             return;
         }
-        if (internalType.equals("long")) {
+        if ("long".equals(internalType)) {
             long[] ll = new long[values.length];
             for (int i = 0; i < values.length; i++) {
                 ll[i] = new Long(values[i]).longValue();
@@ -287,7 +287,7 @@
             m_value = ll;
             return;
         }
-        if (internalType.equals("float")) {
+        if ("float".equals(internalType)) {
             float[] fl = new float[values.length];
             for (int i = 0; i < values.length; i++) {
                 fl[i] = new Float(values[i]).floatValue();
@@ -295,7 +295,7 @@
             m_value = fl;
             return;
         }
-        if (internalType.equals("double")) {
+        if ("double".equals(internalType)) {
             double[] dl = new double[values.length];
             for (int i = 0; i < values.length; i++) {
                 dl[i] = new Double(values[i]).doubleValue();
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
index 6216a8d..2f30e71 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
@@ -95,14 +95,13 @@
         m_serviceSpecification = specification;
         m_factoryPolicy = factoryPolicy;
 
-        // Add service pid and factory pid
-        addProperty(new Property(this, org.osgi.framework.Constants.SERVICE_PID, handler.getInstanceManager().getInstanceName()));       
-        addProperty(new Property(this, "factory.pid", handler.getInstanceManager().getFactory().getName()));
+        // Add instance name & factory name
+        addProperty(new Property(this, "instance.name", handler.getInstanceManager().getInstanceName()));       
+        addProperty(new Property(this, "factory.name", handler.getInstanceManager().getFactory().getName()));
     }
 
     /**
      * Add properties to the provided service.
-     * 
      * @param props : the properties to attached to the service registration
      */
     protected void setProperties(Property[] props) {
@@ -219,8 +218,8 @@
 
     /**
      * Register the service. The service object must be able to serve this
-     * service. To avoid cycle in Check Context, the registred service is set to
-     * registred before the real registration.
+     * service. To avoid cycle in Check Context, the registered service is set to
+     * registered before the real registration.
      */
     protected synchronized void registerService() {
         if (m_serviceRegistration == null) {
@@ -240,11 +239,7 @@
      */
     protected synchronized void unregisterService() {
         if (m_serviceRegistration != null) {
-            try {
-                m_serviceRegistration.unregister();
-            } catch (Exception e) {
-                return;
-            }
+            m_serviceRegistration.unregister();
             m_serviceRegistration = null;
         }
     }
@@ -310,7 +305,6 @@
 
     /**
      * Add properties to the list.
-     * 
      * @param props : properties to add
      */
     protected void addProperties(Dictionary props) {
@@ -325,7 +319,6 @@
 
     /**
      * Remove properties from the list.
-     * 
      * @param props : properties to remove
      */
     protected void deleteProperties(Dictionary props) {
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
index 48d15e5..4ed2549 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -22,8 +22,10 @@
 import java.util.Dictionary;
 import java.util.Properties;
 
-import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.IPojoConfiguration;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
@@ -36,14 +38,13 @@
 import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.parser.ParseUtils;
 import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.Constants;
 
 /**
- * Composite PRovided Service Handler.
- * This handler maange the service providing for a composition.
+ * Composite Provided Service Handler.
+ * This handler manage the service providing for a composition.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ProvidedServiceHandler extends Handler {
+public class ProvidedServiceHandler extends PrimitiveHandler {
 
     /**
      * The list of the provided service.
@@ -51,11 +52,6 @@
     private ProvidedService[] m_providedServices = new ProvidedService[0];
 
     /**
-     * The instance manager.
-     */
-    private InstanceManager m_manager;
-
-    /**
      * Add a provided service to the list .
      * 
      * @param ps : the provided service to add
@@ -63,9 +59,7 @@
     private void addProvidedService(ProvidedService ps) {
         // Verify that the provided service is not already in the array.
         for (int i = 0; (m_providedServices != null) && (i < m_providedServices.length); i++) {
-            if (m_providedServices[i] == ps) {
-                return;
-            }
+            if (m_providedServices[i] == ps) { return; }
         }
 
         if (m_providedServices.length > 0) {
@@ -79,14 +73,6 @@
     }
 
     /**
-     * Get the instance manager.
-     * @return the instance manager.
-     */
-    public InstanceManager getInstanceManager() {
-        return m_manager;
-    }
-
-    /**
      * Get the array of provided service.
      * @return the list of the provided service.
      */
@@ -96,18 +82,14 @@
 
     /**
      * Configure the handler.
-     * @param im : the instance manager
      * @param componentMetadata : the component type metadata
      * @param configuration : the instance configuration
+     * @throws ConfigurationException : the metadata are not correct.
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(InstanceManager im, Element componentMetadata, Dictionary configuration) {
-        // Fix the instance manager & clean the provided service list
-        m_manager = im;
-        
-        ManipulationMetadata manipulation = new ManipulationMetadata(componentMetadata);
+    public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
 
-        ComponentDescription cd = im.getComponentDescription();
+        ManipulationMetadata manipulation = new ManipulationMetadata(componentMetadata);
 
         m_providedServices = new ProvidedService[0];
         // Create the dependency according to the component metadata
@@ -124,14 +106,13 @@
                 serviceSpecification = manipulation.getInterfaces();
             }
             if (serviceSpecification.length == 0) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR,
-                        "Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)");
-                return;
+                log(Logger.ERROR, "Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)");
+                throw new ConfigurationException("Provides  : Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)", getInstanceManager().getFactory().getName());
             }
 
             // Get the factory policy
             int factory = ProvidedService.SINGLETON_FACTORY;
-            if (providedServices[i].containsAttribute("factory") && providedServices[i].getAttribute("factory").equals("service")) {
+            if (providedServices[i].containsAttribute("factory") && "service".equals(providedServices[i].getAttribute("factory"))) {
                 factory = ProvidedService.SERVICE_FACTORY;
             }
 
@@ -175,24 +156,13 @@
 
             if (checkProvidedService(ps, manipulation)) {
                 addProvidedService(ps);
-                // Change ComponentInfo
-                for (int k = 0; k < ps.getServiceSpecification().length; k++) {
-                    cd.addProvidedServiceSpecification(ps.getServiceSpecification()[k]);
-                }
-                for (int k = 0; k < ps.getProperties().length; k++) {
-                    if (!ps.getProperties()[k].getName().equals(Constants.SERVICE_PID) && !ps.getProperties()[k].getName().equals("factory.pid")) {
-                        cd.addProperty(new PropertyDescription(ps.getProperties()[k].getName(), ps.getProperties()[k].getType(), ps.getProperties()[k]
-                                .getInitialValue()));
-                    }
-                }
             } else {
                 String itfs = "";
                 for (int j = 0; j < serviceSpecification.length; j++) {
                     itfs = itfs + " " + serviceSpecification[j];
                 }
-                m_manager.getFactory().getLogger().log(Logger.ERROR,
-                        "[" + m_manager.getClassName() + "] The provided service" + itfs + " is not valid, it will be removed");
-                ps = null;
+                log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The provided service" + itfs + " is not valid");
+                return;
             }
 
         }
@@ -221,8 +191,7 @@
                     }
                 }
             }
-
-            m_manager.register(this, fields, null);
+            getInstanceManager().register(this, fields, null);
         }
     }
 
@@ -233,25 +202,23 @@
      * @param ps : the provided service to check.
      * @param manipulation : component-type manipulation metadata.
      * @return true if the provided service is correct
+     * @throws ConfigurationException : the checked provided service is not correct.
      */
-    private boolean checkProvidedService(ProvidedService ps, ManipulationMetadata manipulation) {
+    private boolean checkProvidedService(ProvidedService ps, ManipulationMetadata manipulation) throws ConfigurationException {
         for (int i = 0; i < ps.getServiceSpecification().length; i++) {
             // Check the implementation of the specification
-            if (! manipulation.isInterfaceImplemented(ps.getServiceSpecification()[i])) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The service specification " + ps.getServiceSpecification()[i]
-                                + " is not implemented by the component class");
-                return false;
+            if (!manipulation.isInterfaceImplemented(ps.getServiceSpecification()[i])) {
+                log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The service specification " + ps.getServiceSpecification()[i] + " is not implemented by the component class");
+                throw new ConfigurationException("Provides  : The service specification " + ps.getServiceSpecification()[i] + " is not implemented by the component class", getInstanceManager().getFactory().getName());
+
             }
-            
+
             // Check service level dependencies
             try {
-                Class spec = m_manager.getFactory().loadClass(ps.getServiceSpecification()[i]);
-                Field specField = spec.getField("specification");     
+                Class spec = getInstanceManager().getFactory().loadClass(ps.getServiceSpecification()[i]);
+                Field specField = spec.getField("specification");
                 Object o = specField.get(null);
-                if (!(o instanceof String)) {
-                    m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The specification field of the service specification " + ps.getServiceSpecification()[i] + " need to be a String");                                                                                                                                                                    
-                    return false;
-                } else {
+                if (o instanceof String) {
                     Element specification = ManifestMetadataParser.parse((String) o);
                     Element[] deps = specification.getElements("requires");
                     for (int j = 0; j < deps.length; j++) {
@@ -260,25 +227,27 @@
                             // Fix service-level dependency flag
                             d.setServiceLevelDependency();
                         }
-                        if (!isDependencyCorrect(d, deps[j])) {
-                            return false;
-                        }
+                        isDependencyCorrect(d, deps[j]);
                     }
+                } else {
+                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The specification field of the service specification " + ps.getServiceSpecification()[i] + " need to be a String");
+                    throw new ConfigurationException("Provides  : The specification field of the service specification " + ps.getServiceSpecification()[i] + " need to be a String", getInstanceManager().getFactory().getName());
                 }
             } catch (NoSuchFieldException e) {
-                return true;  // No specification field
+                return true; // No specification field
             } catch (ClassNotFoundException e) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The service specification " + ps.getServiceSpecification()[i] + " cannot be load");                                                                                                                                                                    
-                return false;
+                log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The service specification " + ps.getServiceSpecification()[i] + " cannot be load");
+                throw new ConfigurationException("Provides  : The service specification " + ps.getServiceSpecification()[i] + " cannot be load", getInstanceManager().getFactory().getName());
             } catch (IllegalArgumentException e) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());                                                                                                                                                                    
-                return false;
+                log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
+                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage(), getInstanceManager().getFactory().getName());
             } catch (IllegalAccessException e) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());                                                                                                                                                                    
-                return false;
+                log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
+                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage(), getInstanceManager().getFactory().getName());
             } catch (ParseException e) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage());                                                                                                                                                                    
-                return false;
+                log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage());
+                throw new ConfigurationException("Provides  :  The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage(), getInstanceManager().getFactory()
+                        .getName());
             }
         }
 
@@ -291,29 +260,23 @@
      * @return the Dependency object, null if not found or if the DependencyHandler is not plugged to the instance
      */
     private Dependency getAttachedDependency(Element element) {
-        DependencyHandler dh = (DependencyHandler) m_manager.getHandler(DependencyHandler.class.getName());
-        if (dh == null) { 
-            return null;
-        }
-        
+        DependencyHandler dh = (DependencyHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
+        if (dh == null) { return null; }
+
         if (element.containsAttribute("id")) {
             // Look for dependency Id
             String id = element.getAttribute("id");
             for (int i = 0; i < dh.getDependencies().length; i++) {
-                if (dh.getDependencies()[i].getId().equals(id)) {
-                    return dh.getDependencies()[i]; 
-                }
+                if (dh.getDependencies()[i].getId().equals(id)) { return dh.getDependencies()[i]; }
             }
         }
-        
+
         // If not found or no id, look for a dependency with the same specification
         String requirement = element.getAttribute("specification");
         for (int i = 0; i < dh.getDependencies().length; i++) {
-            if (dh.getDependencies()[i].getSpecification().equals(requirement)) {
-                return dh.getDependencies()[i]; 
-            }
+            if (dh.getDependencies()[i].getSpecification().equals(requirement)) { return dh.getDependencies()[i]; }
         }
-        
+
         return null;
     }
 
@@ -321,40 +284,39 @@
      * Check the correctness of the implementation dependency against the service level dependency.
      * @param dep : dependency to check
      * @param elem : service-level dependency metadata
-     * @return true if the dependency is correct, false otherwise
+     * @throws ConfigurationException  : the service level dependency and the implementation dependency does not match.
      */
-    private boolean isDependencyCorrect(Dependency dep, Element elem) {
+    private void isDependencyCorrect(Dependency dep, Element elem) throws ConfigurationException {
         boolean opt = false;
         if (elem.containsAttribute("optional") && elem.getAttribute("optional").equalsIgnoreCase("true")) {
             opt = true;
         }
-        
+
         boolean agg = false;
         if (elem.containsAttribute("aggregate") && elem.getAttribute("aggregate").equalsIgnoreCase("true")) {
             agg = true;
         }
 
         if (dep == null && !opt) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The requirement " + elem.getAttribute("specification") + " is not present in the implementation and is declared as a mandatory service-level requirement");
-            return false;
+            log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The requirement " + elem.getAttribute("specification") + " is not present in the implementation and is declared as a mandatory service-level requirement");
+            throw new ConfigurationException("Provides  :  The requirement " + elem.getAttribute("specification") + " is not present in the implementation and is declared as a mandatory service-level requirement", getInstanceManager().getFactory()
+                    .getName());
         }
-        
-        
+
         if (dep != null && dep.isAggregate() && !agg) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
-            return false;
+            log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
+            throw new ConfigurationException("Provides  :  The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement", getInstanceManager().getFactory()
+                    .getName());
         }
-      
+
         if (dep != null && elem.containsAttribute("filter")) {
             String filter = elem.getAttribute("filter");
             String filter2 = dep.getFilter();
             if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {
-                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
-                return false;
+                log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
+                throw new ConfigurationException("Provides  :  The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement", getInstanceManager().getFactory().getName());
             }
         }
-        
-        return true;
     }
 
     /**
@@ -373,11 +335,11 @@
     public void start() {
     }
 
-   /**
-    * Setter Callback Method.
-    * Check if the modified field is a property to update the value.
-    * @param fieldName : field name
-    * @param value : new value
+    /**
+     * Setter Callback Method.
+     * Check if the modified field is a property to update the value.
+     * @param fieldName : field name
+     * @param value : new value
      * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String,
      * java.lang.Object)
      */
@@ -480,7 +442,7 @@
      * @see org.apache.felix.ipojo.Handler#getDescription()
      */
     public HandlerDescription getDescription() {
-        ProvidedServiceHandlerDescription pshd = new ProvidedServiceHandlerDescription(this.isValid());
+        ProvidedServiceHandlerDescription pshd = new ProvidedServiceHandlerDescription(this);
 
         for (int j = 0; j < getProvidedService().length; j++) {
             ProvidedService ps = getProvidedService()[j];
@@ -525,4 +487,75 @@
         }
     }
 
+    /**
+     * Initialize the component type.
+     * @param cd : component type description to populate.
+     * @param metadata : component type metadata.
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     */
+    public void initializeComponentFactory(ComponentDescription cd, Element metadata) {
+        // Change ComponentInfo
+        Element[] provides = metadata.getElements("provides");
+        ManipulationMetadata mm = new ManipulationMetadata(metadata);
+
+        for (int i = 0; i < provides.length; i++) {
+            String[] serviceSpecification = new String[0];
+            if (provides[i].containsAttribute("interface")) {
+                String serviceSpecificationStr = provides[i].getAttribute("interface");
+                serviceSpecification = ParseUtils.parseArrays(serviceSpecificationStr);
+            } else {
+                serviceSpecification = mm.getInterfaces();
+            }
+            if (serviceSpecification.length == 0) {
+                log(Logger.ERROR, "Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)");
+                return;
+            }
+
+            for (int j = 0; j < serviceSpecification.length; j++) {
+                cd.addProvidedServiceSpecification(serviceSpecification[j]);
+            }
+
+            Element[] props = provides[i].getElements("property");
+            for (int j = 0; j < props.length; j++) {
+                String name = null;
+                if (props[j].containsAttribute("name")) {
+                    name = props[j].getAttribute("name");
+                }
+                String value = null;
+                if (props[j].containsAttribute("value")) {
+                    value = props[j].getAttribute("value");
+                }
+                String type = null;
+                if (props[j].containsAttribute("type")) {
+                    type = props[j].getAttribute("type");
+                }
+                String field = null;
+                if (props[j].containsAttribute("field")) {
+                    field = props[j].getAttribute("field");
+                }
+
+                // Get property name :
+                if (field != null && name == null) {
+                    name = field;
+                }
+
+                // Check type if not already set
+                if (type == null) {
+                    if (field == null) {
+                        System.err.println("The property " + name + " has neither type neither field.");
+                        return;
+                    }
+                    FieldMetadata fm = mm.getField(field);
+                    if (fm == null) {
+                        System.err.println("A declared property was not found in the class : " + field);
+                        return;
+                    }
+                    type = fm.getFieldType();
+                }
+
+                cd.addProperty(new PropertyDescription(name, type, value));
+            }
+        }
+    }
+
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
index bd08f40..d2bb779 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
@@ -20,6 +20,7 @@
 
 import java.util.Iterator;
 
+import org.apache.felix.ipojo.Handler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
@@ -39,11 +40,10 @@
 
     /**
      * Constructor.
-     * 
-     * @param isValid : the validity of the provided service handler.
+     * @param h : handler.
      */
-    public ProvidedServiceHandlerDescription(boolean isValid) {
-        super(ProvidedServiceHandler.class.getName(), isValid);
+    public ProvidedServiceHandlerDescription(Handler h) {
+        super(h);
     }
 
     /**
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
index a736115..f993a2e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
@@ -49,7 +49,8 @@
     public Element[] getComponentsMetadata() throws ParseException {
         Element[] components = m_elements[0].getElements("Component");
         Element[] composites = m_elements[0].getElements("Composite");
-        Element[] all = new Element[components.length + composites.length];
+        Element[] handlers = m_elements[0].getElements("Handler");
+        Element[] all = new Element[components.length + composites.length + handlers.length];
         int l = 0;
         for (int i = 0; i < components.length; i++) {
             all[l] = components[i];
@@ -59,6 +60,10 @@
             all[l] = composites[i];
             l++;
         }
+        for (int i = 0; i < handlers.length; i++) {
+            all[l] = handlers[i];
+            l++;
+        }
         return all;
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java
index e7c51b7..702793e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java
@@ -22,7 +22,7 @@
 
 /**
  * Manipulation Metadata allows getting information about the implementation class
- * whithout doing reflection. 
+ * without doing reflection. 
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
@@ -52,16 +52,19 @@
      */
     public ManipulationMetadata(Element metadata) {
         Element manip = metadata.getElements("manipulation", "")[0];
-        for (int i = 0; i < manip.getElements().length; i++) {
-            if (manip.getElements()[i].getName().equals("field")) {
-                FieldMetadata fm = new FieldMetadata(manip.getElements()[i]);
-                addField(fm);
-            } else if (manip.getElements()[i].getName().equals("method")) {
-                MethodMetadata fm = new MethodMetadata(manip.getElements()[i]);
-                addMethod(fm);
-            } else if (manip.getElements()[i].getName().equals("interface")) {
-                addInterface(manip.getElements()[i].getAttribute("name"));
-            }
+        Element[] fields = manip.getElements("field");
+        for (int i = 0; i < fields.length; i++) {
+            FieldMetadata fm = new FieldMetadata(fields[i]);
+            addField(fm);
+        }
+        Element[] methods = manip.getElements("method");
+        for (int i = 0; i < methods.length; i++) {
+            MethodMetadata fm = new MethodMetadata(methods[i]);
+            addMethod(fm);
+        }
+        Element[] itfs = manip.getElements("interface");
+        for (int i = 0; i < itfs.length; i++) {
+            addInterface(itfs[i].getAttribute("name"));
         }
     }
     
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
index 2676dcc..b90e6b6 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
@@ -293,7 +293,7 @@
      * @param arg : the parameters
      * @return the result of the invocation, null for void method, the last result for multi-object instance
      * @throws NoSuchMethodException : the callback method is not found
-     * @throws IllegalAccessException : the callbback method cannot be called
+     * @throws IllegalAccessException : the callback method cannot be called
      * @throws InvocationTargetException : an error occurs inside the called
      * method
      */
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
index 93f4daa..30a33a2 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
@@ -75,7 +75,6 @@
         m_name = name;
         m_level = level;
         m_context = bc;
-
     }
 
     /**
@@ -86,9 +85,7 @@
      */
     public void log(int level, String msg) {
         if (m_level >= level) {
-            synchronized (this) {
-                dispatch(level, msg, null);
-            }
+            dispatch(level, msg, null);
         }
     }
 
@@ -101,9 +98,7 @@
      */
     public void log(int level, String msg, Throwable ex) {
         if (m_level >= level) {
-            synchronized (this) {
-                dispatch(level, msg, ex);
-            }
+            dispatch(level, msg, ex);
         }
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
new file mode 100644
index 0000000..0c84d2e
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
@@ -0,0 +1,745 @@
+/* 

+ * 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.util;

+

+import java.util.ArrayList;

+import java.util.Comparator;

+import java.util.Iterator;

+import java.util.LinkedList;

+import java.util.List;

+import java.util.TreeMap;

+

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Constants;

+import org.osgi.framework.Filter;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceEvent;

+import org.osgi.framework.ServiceListener;

+import org.osgi.framework.ServiceReference;

+

+/**

+* Utility class close to the OSGi Service Tracker.

+* 

+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+*/

+public class Tracker implements TrackerCustomizer {

+

+    /**

+     * Bundle context against which this Tracker object is tracking.

+     */

+    protected final BundleContext m_context;

+

+    /**

+     * Filter specifying search criteria for the services to track.

+     */

+    protected Filter m_filter;

+

+    /**

+     * TrackerCustomizer object for this tracker.

+     */

+    final TrackerCustomizer m_customizer;

+

+    /**

+     * Filter string for use when adding the ServiceListener. If this field is set, then certain optimizations can be taken since we don't have a user supplied filter.

+     */

+    final String m_listenerFilter;

+

+    /**

+     * Class name to be tracked. If this field is set, then we are tracking by class name.

+     */

+    private final String m_trackClass;

+

+    /**

+     * Reference to be tracked. If this field is set, then we are tracking a single ServiceReference.

+     */

+    private final ServiceReference m_trackReference;

+

+    /**

+     * Tracked services: ServiceReference object -> customized. Object and ServiceListener object

+     */

+    private Tracked m_tracked;

+

+    /**

+     * Cached ServiceReference for getServiceReference. This field is volatile since it is accessed by multiple threads.

+     */

+    private volatile ServiceReference m_cachedReference;

+

+    /**

+     * Cached service object for getService. This field is volatile since it is accessed by multiple threads.

+     */

+    private volatile Object m_cachedService;

+

+    /**

+     * Create a Tracker object on the specified ServiceReference object.

+     * The service referenced by the specified ServiceReference object will be tracked by this Tracker.

+     * @param context BundleContext object against which the tracking is done.

+     * @param reference ServiceReference object for the service to be tracked.

+     * @param customizer The customizer object to call when services are added, modified, or removed in this Tracker object. If customizer is null, then this Tracker object will be used as

+     *            the TrackerCustomizer object and the Tracker object will call the TrackerCustomizer methods on itself.

+     */

+    public Tracker(BundleContext context, ServiceReference reference, TrackerCustomizer customizer) {

+        m_context = context;

+        m_trackReference = reference;

+        m_trackClass = null;

+        if (customizer == null) {

+            m_customizer = this;

+        } else {

+            m_customizer = customizer;

+        }

+        m_listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

+        try {

+            this.m_filter = context.createFilter(m_listenerFilter);

+        } catch (InvalidSyntaxException e) { // we could only get this exception if the ServiceReference was invalid

+            throw new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$

+        }

+    }

+

+    /**

+     * Create a Tracker object on the specified class name.

+     * Services registered under the specified class name will be tracked by this Tracker object.

+     * @param context BundleContext object against which the tracking is done.

+     * @param clazz Class name of the services to be tracked.

+     * @param customizer The customizer object to call when services are added, modified, or removed in this Tracker object. If customizer is null, then this Tracker object will be used as

+     *            the TrackerCustomizer object and the Tracker object will call the TrackerCustomizer methods on itself.

+     */

+    public Tracker(BundleContext context, String clazz, TrackerCustomizer customizer) {

+        this.m_context = context;

+        this.m_trackReference = null;

+        this.m_trackClass = clazz;

+        if (customizer == null) {

+            m_customizer = this;

+        } else {

+            m_customizer = customizer;

+        }

+        this.m_listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

+        try {

+            this.m_filter = context.createFilter(m_listenerFilter);

+        } catch (InvalidSyntaxException e) { // we could only get this exception

+            // if the clazz argument was

+            // malformed

+            throw new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$

+        }

+    }

+

+    /**

+     * Create a Tracker object on the specified Filter object.

+     * <p>

+     * Services which match the specified Filter object will be tracked by this Tracker object.

+     * @param context BundleContext object against which the tracking is done.

+     * @param filter Filter object to select the services to be tracked.

+     * @param customizer The customizer object to call when services are added, modified, or removed in this Tracker object. If customizer is null, then this Tracker object will be used as the

+     *            TrackerCustomizer object and the Tracker object will call the TrackerCustomizer methods on itself.

+     * @since 1.1

+     */

+    public Tracker(BundleContext context, Filter filter, TrackerCustomizer customizer) {

+        this.m_context = context;

+        this.m_trackReference = null;

+        this.m_trackClass = null;

+        this.m_listenerFilter = null;

+        this.m_filter = filter;

+        if (customizer == null) {

+            m_customizer = this;

+        } else {

+            m_customizer = customizer;

+        }

+        if ((context == null) || (filter == null)) { // we throw a NPE here to be consistent with the other constructors

+            throw new NullPointerException();

+        }

+    }

+

+    /**

+     * Open this Tracker object and begin tracking services.

+     * <p>

+     * Services which match the search criteria specified when this Tracker object was created are now tracked by this Tracker object.

+     */

+    public synchronized void open() {

+        if (m_tracked != null) { return; }

+

+        m_tracked = new Tracked();

+        synchronized (m_tracked) {

+            try {

+                m_context.addServiceListener(m_tracked, m_listenerFilter);

+                ServiceReference[] references;

+                if (m_listenerFilter == null) { // user supplied filter

+                    references = getInitialReferences(null, m_filter.toString());

+                } else { // constructor supplied filter

+                    if (m_trackClass == null) {

+                        references = new ServiceReference[] { m_trackReference };

+                    } else {

+                        references = getInitialReferences(m_trackClass, null);

+                    }

+                }

+

+                m_tracked.setInitialServices(references); // set tracked with

+                // the initial

+                // references

+            } catch (InvalidSyntaxException e) {

+                throw new RuntimeException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$

+            }

+        }

+        /* Call tracked outside of synchronized region */

+        m_tracked.trackInitialServices(); // process the initial references

+    }

+

+    /**

+     * Returns the list of initial ServiceReference objects that will be tracked by this Tracker object.

+     * @param trackClass the class name with which the service was registered, or null for all services.

+     * @param filterString the filter criteria or null for all services.

+     * @return the list of initial ServiceReference objects.

+     * @throws InvalidSyntaxException if the filter uses an invalid syntax.

+     */

+    private ServiceReference[] getInitialReferences(String trackClass, String filterString) throws InvalidSyntaxException {

+        return m_context.getServiceReferences(trackClass, filterString);

+    }

+

+    /**

+     * Close this Tracker object.

+     * <p>

+     * This method should be called when this Tracker object should end the tracking of services.

+     */

+    public synchronized void close() {

+        if (m_tracked == null) { return; }

+

+        m_tracked.close();

+        ServiceReference[] references = getServiceReferences();

+        Tracked outgoing = m_tracked;

+        m_tracked = null;

+        try {

+            m_context.removeServiceListener(outgoing);

+        } catch (IllegalStateException e) {

+            System.err.println("Context stopped");

+            /* In case the context was stopped. */

+        }

+        if (references != null) {

+            for (int i = 0; i < references.length; i++) {

+                outgoing.untrack(references[i]);

+            }

+        }

+

+    }

+

+    /**

+     * Default implementation of the TrackerCustomizer.addingService method.

+     * <p>

+     * This method is only called when this Tracker object has been constructed with a null TrackerCustomizer argument. The default implementation returns the result of calling getService,

+     * on the BundleContext object with which this Tracker object was created, passing the specified ServiceReference object.

+     * <p>

+     * This method can be overridden in a subclass to customize the service object to be tracked for the service being added. In that case, take care not to rely on the default implementation of removedService that will unget the service.

+     * @param reference Reference to service being added to this Tracker object.

+     * @return The service object to be tracked for the service added to this Tracker object.

+     * @see TrackerCustomizer

+     */

+    public boolean addingService(ServiceReference reference) {

+        return true;

+    }

+

+    /**

+     * Default implementation of the TrackerCustomizer.modifiedService method.

+     * <p>

+     * This method is only called when this Tracker object has been constructed with a null TrackerCustomizer argument. The default implementation does nothing.

+     * @param reference Reference to modified service.

+     * @param service The service object for the modified service.

+     * @see TrackerCustomizer

+     */

+    public void modifiedService(ServiceReference reference, Object service) {

+    }

+

+    /**

+     * Default implementation of the TrackerCustomizer.removedService method.

+     * <p>

+     * This method is only called when this Tracker object has been constructed with a null TrackerCustomizer argument. The default implementation calls ungetService, on the

+     * BundleContext object with which this Tracker object was created, passing the specified ServiceReference object.

+     * <p>

+     * This method can be overridden in a subclass. If the default implementation of addingService method was used, this method must unget the service.

+     * @param reference Reference to removed service.

+     * @param service The service object for the removed service.

+     * @see TrackerCustomizer

+     */

+    public void removedService(ServiceReference reference, Object service) {

+        m_context.ungetService(reference);

+    }

+

+    /**

+     * Wait for at least one service to be tracked by this Tracker object.

+     * <p>

+     * It is strongly recommended that waitForService is not used during the calling of the BundleActivator methods. BundleActivator methods are expected to complete in a short period of time.

+     * @param timeout time interval in milliseconds to wait. If zero, the method will wait indefinately.

+     * @return Returns the result of getService().

+     * @throws InterruptedException If another thread has interrupted the current thread.

+     */

+    public Object waitForService(long timeout) throws InterruptedException {

+        if (timeout < 0) { throw new IllegalArgumentException("timeout value is negative"); }

+        Object object = getService();

+        while (object == null) {

+            Tracked tracked = this.m_tracked; // use local var since we are not synchronized

+            if (tracked == null) { /* if Tracker is not open */

+                return null;

+            }

+            synchronized (tracked) {

+                if (tracked.size() == 0) {

+                    tracked.wait(timeout);

+                }

+            }

+            object = getService();

+            if (timeout > 0) { return object; }

+        }

+        return object;

+    }

+

+    /**

+     * Return an array of ServiceReference objects for all services being tracked by this Tracker object.

+     * @return Array of ServiceReference objects or null if no service are being tracked.

+     */

+    public ServiceReference[] getServiceReferences() {

+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized

+        if (tracked == null) { // if Tracker is not open

+            return null;

+        }

+        synchronized (tracked) {

+            int length = tracked.size();

+            if (length == 0) { return null; }

+            ServiceReference[] references = new ServiceReference[length];

+            Iterator keys = tracked.keySet().iterator();

+            for (int i = 0; i < length; i++) {

+                references[i] = (ServiceReference) keys.next();

+            }

+            // The resulting array is sorted by ranking.

+            return references;

+        }

+    }

+    

+    /**

+     * Get the list of stored service reference.

+     * @return the list containing used service reference

+     */

+    public List/*<ServiceReference>*/ getServiceReferencesList() {

+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized

+        if (tracked == null) { // if Tracker is not open

+            return null;

+        }

+        synchronized (tracked) {

+            int length = tracked.size();

+            if (length == 0) { return null; }

+            List references = new ArrayList(length);

+            Iterator keys = tracked.keySet().iterator();

+            for (int i = 0; i < length; i++) {

+                references.add(keys.next());

+            }

+            // The resulting array is sorted by ranking.

+            return references;

+        }

+    }

+

+    /**

+     * Returns a ServiceReference object for one of the services being tracked by this Tracker object.

+     * If multiple services are being tracked, the service with the highest ranking (as specified in its service.ranking property) is returned.

+     * If there is a tie in ranking, the service with the lowest service ID (as specified in its service.id property); that is, the service that was registered first is returned.

+     * This is the same algorithm used by BundleContext.getServiceReference.

+     * @return ServiceReference object or null if no service is being tracked.

+     * @since 1.1

+     */

+    public ServiceReference getServiceReference() {

+        ServiceReference reference = m_cachedReference;

+        if (reference != null) { return reference; }

+

+        ServiceReference[] references = getServiceReferences();

+        if (references == null) {

+            return null;

+        } else {

+            // As the map is sorted, return the first element.

+            return m_cachedReference = references[0];

+        }

+    }

+

+    /**

+     * Returns the service object for the specified ServiceReference object if the referenced service is being tracked by this Tracker object.

+     * @param reference Reference to the desired service.

+     * @return Service object or null if the service referenced by the specified ServiceReference object is not being tracked.

+     */

+    public Object getService(ServiceReference reference) {

+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized

+        if (tracked == null) { /* if Tracker is not open */

+            return null;

+        }

+        Object object = null;

+        synchronized (tracked) {

+            object =  tracked.get(reference);

+            if (object != null) { // The object was already get.

+                return object;

+            } else if (tracked.containsKey(reference)) { // Not already get

+                object = m_context.getService(reference);

+                tracked.put(reference, object);

+                return object;

+            }

+        }

+        // Not already tracked.

+        return m_context.getService(reference);

+    }

+    

+    /**

+     * Unget the given service reference.

+     * @param reference : service reference to unget.

+     */

+    public void ungetService(ServiceReference reference) {

+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized

+        if (tracked == null) { /* if Tracker is not open */

+            return;

+        }

+        Object object = null;

+        synchronized (tracked) {

+            object = tracked.get(reference);

+        }

+        if (object != null) { m_context.ungetService(reference); }

+    }

+

+    /**

+     * Return an array of service objects for all services being tracked by this Tracker object.

+     * @return Array of service objects or null if no service are being tracked.

+     */

+    public Object[] getServices() {

+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized

+        if (tracked == null) { /* if Tracker is not open */

+            return null;

+        }

+        synchronized (tracked) {

+            ServiceReference[] references = getServiceReferences();

+            int length = 0;

+            if (references != null) {

+                length = references.length;

+            } else {

+                return null; 

+            }

+            Object[] objects = new Object[length];

+            for (int i = 0; i < length; i++) {

+                objects[i] = getService(references[i]);

+            }

+            return objects;

+        }

+    }

+

+    /**

+     * Returns a service object for one of the services being tracked by this Tracker object.

+     * <p>

+     * If any services are being tracked, this method returns the result of calling getService(getServiceReference()).

+     * @return Service object or null if no service is being tracked.

+     */

+    public Object getService() {

+        Object service = m_cachedService;

+        if (service != null) { return service; }

+        ServiceReference reference = getServiceReference();

+        if (reference == null) { return null; }

+        return m_cachedService = getService(reference);

+    }

+

+    /**

+     * Remove a service from this Tracker object. The specified service will be removed from this Tracker object. If the specified service was being tracked then the

+     * TrackerCustomizer.removedService method will be called for that service.

+     * @param reference Reference to the service to be removed.

+     */

+    public void remove(ServiceReference reference) {

+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized

+        if (tracked == null) { /* if Tracker is not open */

+            return;

+        }

+        tracked.untrack(reference);

+    }

+

+    /**

+     * Return the number of services being tracked by this Tracker object.

+     * @return Number of services being tracked.

+     */

+    public int size() {

+        Tracked tracked = this.m_tracked; //use local var since we are not synchronized

+        if (tracked == null) { /* if Tracker is not open */

+            return 0;

+        }

+        return tracked.size();

+    }

+

+    /**

+     * Inner class to track services. If a Tracker object is reused (closed then reopened), then a new Tracked object is used. This class is a hashtable mapping ServiceReference object -> customized Object. This

+     * class is the ServiceListener object for the tracker. This class is used to synchronize access to the tracked services. This is not a public class. It is only for use by the implementation of the Tracker

+     * class.

+     */

+    class Tracked extends TreeMap implements ServiceListener {

+        /**

+         * UID.

+         */

+        static final long serialVersionUID = -7420065199791006079L;

+    

+        /**

+         * List of ServiceReferences in the process of being added. This is used to deal with nesting of ServiceEvents. Since ServiceEvents are synchronously delivered, ServiceEvents can be nested. For example, when processing the adding of a service

+         * and the customizer causes the service to be unregistered, notification to the nested call to untrack that the service was unregistered can be made to the track method. Since the ArrayList implementation is not synchronized, all access to

+         * this list must be protected by the same synchronized object for thread safety.

+         */

+        private List m_adding;

+    

+        /**

+         * true if the tracked object is closed. This field is volatile because it is set by one thread and read by another.

+         */

+        private volatile boolean m_closed;

+    

+        /**

+         * Initial list of ServiceReferences for the tracker. This is used to correctly process the initial services which could become unregistered before they are tracked. This is necessary since the initial set of tracked services are not

+         * "announced" by ServiceEvents and therefore the ServiceEvent for unregistration could be delivered before we track the service. A service must not be in both the initial and adding lists at the same time. A service must be moved from the

+         * initial list to the adding list "atomically" before we begin tracking it. Since the LinkedList implementation is not synchronized, all access to this list must be protected by the same synchronized object for thread safety.

+         */

+        private List m_initial;

+    

+        /**

+         * Tracked constructor.

+         */

+        protected Tracked() {

+            super(new ReferenceComparator());

+            m_closed = false;

+            m_adding = new ArrayList(6);

+            m_initial = new LinkedList();

+        }

+    

+        /**

+         * Set initial list of services into tracker before ServiceEvents begin to be received. This method must be called from Tracker.open while synchronized on this object in the same synchronized block as the addServiceListener call.

+         * @param references The initial list of services to be tracked.

+         */

+        protected void setInitialServices(ServiceReference[] references) {

+            if (references == null) { return; }

+            int size = references.length;

+            for (int i = 0; i < size; i++) {

+                m_initial.add(references[i]);

+            }

+        }

+    

+        /**

+         * Track the initial list of services. This is called after ServiceEvents can begin to be received. This method must be called from Tracker.open while not synchronized on this object after the addServiceListener call.

+         */

+        protected void trackInitialServices() {

+            while (true) {

+                ServiceReference reference;

+                synchronized (this) {

+                    if (m_initial.size() == 0) { //  if there are no more inital services

+                        return; // we are done

+                    }

+    

+                    // move the first service from the initial list to the adding list within this synchronized block.

+                    reference = (ServiceReference) ((LinkedList) m_initial).removeFirst();

+                    if (this.containsKey(reference)) { //Check if the reference is already tracked.

+                        //if we are already tracking this service

+                        continue; /* skip this service */

+                    }

+                    if (m_adding.contains(reference)) {

+                        // if this service is already in the process of being added.

+                        continue; // skip this service

+                    }

+                    m_adding.add(reference);

+                }

+                trackAdding(reference); // Begin tracking it. We call trackAdding since we have already put the reference in the adding list.

+            }

+        }

+    

+        /**

+         * Called by the owning Tracker object when it is closed.

+         */

+        protected void close() {

+            m_closed = true;

+        }

+    

+        /**

+         * ServiceListener method for the Tracker class. This method must NOT be synchronized to avoid deadlock potential.

+         * @param event ServiceEvent object from the framework.

+         */

+        public void serviceChanged(ServiceEvent event) {

+            //Check if we had a delayed call (which could happen when we close).

+            if (m_closed) { return; }

+            ServiceReference reference = event.getServiceReference();

+    

+            switch (event.getType()) {

+                case ServiceEvent.REGISTERED:

+                case ServiceEvent.MODIFIED:

+                    if (m_listenerFilter != null) { // constructor supplied filter

+                        track(reference);

+                    } else { // user supplied filter

+                        if (m_filter.match(reference)) {

+                            track(reference); // Arrival

+                        } else {

+                            untrack(reference); // Departure

+                        }

+                    }

+                    break;

+                case ServiceEvent.UNREGISTERING:

+                    untrack(reference); // Departure

+                    break;

+                default:

+                    break;

+            }

+        }

+    

+        /**

+         * Begin to track the referenced service.

+         * @param reference Reference to a service to be tracked.

+         */

+        protected void track(ServiceReference reference) {

+            Object object;

+            boolean alreadyTracked;

+            synchronized (this) {

+                alreadyTracked = this.containsKey(reference);

+                object = this.get(reference);

+            }

+            if (alreadyTracked) { // we are already tracking the service

+                if (object != null) { // If already get, invalidate the cache

+                    synchronized (this) {

+                        modified();

+                    }

+                }

+                // Call customizer outside of synchronized region

+                m_customizer.modifiedService(reference, object);

+                return;

+            }

+            synchronized (this) {

+                if (m_adding.contains(reference)) { // if this service is already in the process of being added.

+                    return;

+                }

+                m_adding.add(reference); // mark this service is being added

+            }

+    

+            trackAdding(reference); // call trackAdding now that we have put the reference in the adding list

+        }

+    

+        /**

+         * Common logic to add a service to the tracker used by track and trackInitialServices. The specified reference must have been placed in the adding list before calling this method.

+         * @param reference Reference to a service to be tracked.

+         */

+        private void trackAdding(ServiceReference reference) {

+            boolean mustBeTracked = false;

+            boolean becameUntracked = false;

+            //Call customizer outside of synchronized region

+            try {

+                mustBeTracked = m_customizer.addingService(reference);

+            } finally {

+                synchronized (this) {

+                    if (m_adding.remove(reference)) { // if the service was not untracked during the customizer callback

+                        if (mustBeTracked) {

+                            this.put(reference, null);

+                            modified();

+                            notifyAll(); // notify any waiters in waitForService

+                        }

+                    } else {

+                        becameUntracked = true;

+                    }

+                }

+            }

+            /*

+             * The service became untracked during the customizer callback.

+             */

+            if (becameUntracked) {

+                /* Call customizer outside of synchronized region */

+                m_customizer.removedService(reference, null);

+            }

+        }

+    

+        /**

+         * Discontinue tracking the referenced service.

+         * @param reference Reference to the tracked service.

+         */

+        protected void untrack(ServiceReference reference) {

+            Object object;

+            synchronized (this) {

+                if (m_initial.remove(reference)) { // if this service is already in the list of initial references to process

+                    return; // we have removed it from the list and it will not be processed

+                }

+    

+                if (m_adding.remove(reference)) { // if the service is in the process of being added

+                    return; // in case the service is untracked while in the process of adding

+                }

+                

+                boolean isTraked = this.containsKey(reference); // Check if we was tracking the reference 

+                object = this.remove(reference); // must remove from tracker before calling customizer callback

+                 

+                if (! isTraked) { return; }

+                modified();

+            }

+            // Call customizer outside of synchronized region

+            m_customizer.removedService(reference, object);

+            // If the customizer throws an unchecked exception, it is safe to let it propagate

+        }

+

+        /**

+         * Called by the Tracked object whenever the set of tracked services is modified. Increments the tracking count and clears the cache.

+         * This method must not be synchronized since it is called by Tracked while Tracked is synchronized. We don't want synchronization interactions between the ServiceListener thread and the user thread.

+         */

+        void modified() {

+            m_cachedReference = null; /* clear cached value */

+            m_cachedService = null; /* clear cached value */

+        }

+        

+    }

+

+    /**

+     *Service Reference Comparator.

+     */

+    private class ReferenceComparator implements Comparator {

+

+        /**

+         * Compare two service reference.

+         * @param ref1 : reference 1

+         * @param ref2 : reference 2

+         * @return -1 if the reference 1 is 'higher' than the reference 2, 1 otherwise. (higher is term of ranking means a lower index)

+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)

+         */

+        public int compare(Object ref1, Object ref2) {

+            if (ref1.equals(ref2)) {

+                return 0;

+            }

+            

+            if (ref1 instanceof ServiceReference && ref2 instanceof ServiceReference) {                

+                Object property1 = ((ServiceReference) ref1).getProperty(Constants.SERVICE_RANKING);

+                Object property2 = ((ServiceReference) ref2).getProperty(Constants.SERVICE_RANKING);

+                

+                int rank1 = 0;

+                int rank2 = 0;

+                if (property1 instanceof Integer) { rank1 = ((Integer) property1).intValue(); }

+                if (property2 instanceof Integer) { rank2 = ((Integer) property2).intValue(); }

+                

+                if (rank1 == rank2) {

+                    // Check service.id

+                    Object sid1 = ((ServiceReference) ref1).getProperty(Constants.SERVICE_ID);

+                    Object sid2 = ((ServiceReference) ref2).getProperty(Constants.SERVICE_ID);

+                    

+                    long rankId1 = ((Long) sid1).longValue();

+                    long rankId2 = ((Long) sid2).longValue();

+                    

+                    if (rankId1 == rankId2) {

+                        return 0;

+                    } else if (rankId1 < rankId2) {

+                        return -1;

+                    } else {

+                        return 1;

+                    }

+                    

+                } else if (rank1 > rank2) {

+                    return 1;

+                } else {

+                    return -1;

+                }

+                

+            } else {

+                return 0;

+            }

+        }

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/TrackerCustomizer.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/TrackerCustomizer.java
new file mode 100644
index 0000000..4e731d1
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/TrackerCustomizer.java
@@ -0,0 +1,54 @@
+/* 

+ * 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.util;

+

+import org.osgi.framework.ServiceReference;

+

+/**

+ * Tracker Customizer.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public interface TrackerCustomizer {

+

+    /**

+     * A service is being added to the Tracker object.

+     * This method is called before a service which matched the search parameters of the Tracker object is added to it. This method should return the service object to be tracked for this ServiceReference object.

+     * The returned service object is stored in the Tracker object and is available from the getService and getServices methods.

+     * @param reference Reference to service being added to the Tracker object.

+     * @return The service object to be tracked for the ServiceReference object or null if the ServiceReference object should not be tracked.

+     */

+    boolean addingService(ServiceReference reference);

+

+    /**

+     * A service tracked by the Tracker object has been modified.

+     * This method is called when a service being tracked by the Tracker object has had it properties modified.

+     * @param reference Reference to service that has been modified.

+     * @param service The service object for the modified service.

+     */

+    void modifiedService(ServiceReference reference, Object service);

+

+    /**

+     * A service tracked by the Tracker object has been removed.

+     * This method is called after a service is no longer being tracked by the Tracker object.

+     * @param reference Reference to service that has been removed.

+     * @param service The service object for the removed service.

+     */

+    void removedService(ServiceReference reference, Object service);

+

+}

diff --git a/ipojo/core/src/main/resources/metadata.xml b/ipojo/core/src/main/resources/metadata.xml
new file mode 100644
index 0000000..6b16ad9
--- /dev/null
+++ b/ipojo/core/src/main/resources/metadata.xml
@@ -0,0 +1,41 @@
+<ipojo>

+<!-- Primitives handler -->

+<handler classname="org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler" name="controller"/>

+<handler classname="org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler" name="callback"/>

+<handler classname="org.apache.felix.ipojo.handlers.dependency.DependencyHandler" name="requires">

+	<controller field="m_state"/>

+</handler>

+<handler classname="org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler" name="provides"/>

+<handler classname="org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler" name="properties"/>

+<handler classname="org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler" name="architecture">

+	<provides>

+		<property field="m_name" name="instance.name" value=""/>

+	</provides>

+</handler>

+

+<!-- Composite Handler -->

+<handler classname="org.apache.felix.ipojo.composite.instance.InstanceHandler" name="instance" type="composite">

+	<controller field="m_isValid"/>

+	<requires filter="(factory.state=1)" field="m_factories" optional="true">

+		<callback type="bind" method="bindFactory"/>

+		<callback type="unbind" method="unbindFactory"/>

+	</requires>

+</handler>

+<handler classname="org.apache.felix.ipojo.composite.service.importer.ImportHandler" name="requires" type="composite">

+	<controller field="m_valid"/>

+</handler>

+<handler classname="org.apache.felix.ipojo.composite.service.importer.ExportHandler" name="exports" type="composite">

+	<controller field="m_valid"/>

+</handler>

+<handler classname="org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler" name="service" type="composite">

+	<controller field="m_isValid"/>

+</handler>

+<handler classname="org.apache.felix.ipojo.composite.service.provides.ProvidedServiceHandler" name="provides" type="composite">

+	<controller field="m_valid"/>

+</handler>

+<handler classname="org.apache.felix.ipojo.composite.architecture.ArchitectureHandler" name="architecture" type="composite">

+	<provides>

+		<property field="m_name" name="instance.name" value=""/>

+	</provides>

+</handler>

+</ipojo>
\ No newline at end of file
diff --git a/ipojo/manipulator/pom.xml b/ipojo/manipulator/pom.xml
index 01aabb0..8034a58 100644
--- a/ipojo/manipulator/pom.xml
+++ b/ipojo/manipulator/pom.xml
@@ -9,8 +9,10 @@
   <modelVersion>4.0.0</modelVersion>
   <packaging>bundle</packaging>
   <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
-  <version>0.7.3-SNAPSHOT</version>
-  <name>Apache Felix iPOJO Manipulator</name>
+  <version>0.7.5-SNAPSHOT</version>
+  <name>Apache Felix iPOJO Manipulator</name>

+  

+  
   <dependencies>
     <dependency>
       <groupId>asm</groupId>
@@ -20,18 +22,18 @@
     <dependency>
       <groupId>asm</groupId>
       <artifactId>asm-commons</artifactId>
-      <version>3.0</version>
-      <exclusions>
-    	<exclusion>
-      		<groupId>asm</groupId>
-      		<artifactId>asm-tree</artifactId>
-    	</exclusion>
+      <version>3.0</version>

+      <exclusions>

+    	<exclusion>

+      		<groupId>asm</groupId>

+      		<artifactId>asm-tree</artifactId>

+    	</exclusion>

   	   </exclusions>
     </dependency>
     <dependency>
       <groupId>${pom.groupId}</groupId>
       <artifactId>org.apache.felix.ipojo.metadata</artifactId>
-      <version>0.7.3-SNAPSHOT</version>
+      <version>0.7.5-SNAPSHOT</version>
     </dependency>
   </dependencies>
   <build>
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
index edebd42..7d81c2b 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
@@ -60,15 +60,15 @@
      * Helper array for byte code manipulation of primitive type.

      */

     protected static final String[][] PRIMITIVE_BOXING_INFORMATION = new String[][] { 

-        { "V", "ILLEGAL", "ILLEGAL" }, 

-        { "Z", "java/lang/Boolean", "booleanValue" },

-        { "C", "java/lang/Character", "charValue" }, 

-        { "B", "java/lang/Byte", "byteValue" }, 

-        { "S", "java/lang/Short", "shortValue" }, 

-        { "I", "java/lang/Integer", "intValue" },

-        { "F", "java/lang/Float", "floatValue" }, 

-        { "J", "java/lang/Long", "longValue" }, 

-        { "D", "java/lang/Double", "doubleValue" }

+        {"V", "ILLEGAL", "ILLEGAL"}, 

+        {"Z", "java/lang/Boolean", "booleanValue"},

+        {"C", "java/lang/Character", "charValue"}, 

+        {"B", "java/lang/Byte", "byteValue"}, 

+        {"S", "java/lang/Short", "shortValue"}, 

+        {"I", "java/lang/Integer", "intValue"},

+        {"F", "java/lang/Float", "floatValue"}, 

+        {"J", "java/lang/Long", "longValue"}, 

+        {"D", "java/lang/Double", "doubleValue"}

     };

     

     /**

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
index 2cad656..c1070ae 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
@@ -141,6 +141,7 @@
                 ManipulationProperty.getLogger().log(ManipulationProperty.INFO, "Put the file " + clazz.getAbsolutePath() + " in the jar file");

             } catch (Exception e) {

                 System.err.println("Problem to write the adapted class on the file system " + " [ " + clazz.getAbsolutePath() + " ] " + e.getMessage());

+                e.printStackTrace();

             }

         }

         // The file is in the bundle

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
index 8234d25..7ac4226 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
@@ -173,10 +173,8 @@
      */

     public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {

         // Avoid manipulating special method

-		if (name.equals("<clinit>") || name.equals("class$")) {

-            return super.visitMethod(access, name, desc, signature, exceptions);

-        }

-		// The constructor is manipulated separatly

+        if (name.equals("<clinit>") || name.equals("class$")) { return super.visitMethod(access, name, desc, signature, exceptions); }

+        // The constructor is manipulated separatly

         if (name.equals("<init>")) {

             // 1) change the constructor descriptor (add a component manager arg as first argument)

             String newDesc = desc.substring(1);

@@ -188,16 +186,12 @@
             if (mv == null) {

                 return null;

             } else {

-                //return new ConstructorCodeAdapter(mv, access, desc, m_owner);

+                // return new ConstructorCodeAdapter(mv, access, desc, m_owner);

                 return new ConstructorCodeAdapter(mv, m_owner);

             }

         } else { // "Normal methods"

-

-			// avoid manipulating static methods.

-		  	if ((access & ACC_STATIC) == ACC_STATIC) {

-		  			return super.visitMethod(access, name, desc, signature, exceptions);

-            }

-			

+            // avoid manipulating static methods.

+            if ((access & ACC_STATIC) == ACC_STATIC) { return super.visitMethod(access, name, desc, signature, exceptions); }

             Type[] args = Type.getArgumentTypes(desc);

             String id = name;

             for (int i = 0; i < args.length; i++) {

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
index 066829f..15f6e32 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
@@ -40,6 +40,7 @@
 

 import org.apache.felix.ipojo.manipulation.Manipulator;

 import org.apache.felix.ipojo.manipulation.annotations.MetadataCollector;

+import org.apache.felix.ipojo.metadata.Attribute;

 import org.apache.felix.ipojo.metadata.Element;

 import org.apache.felix.ipojo.xml.parser.ParseException;

 import org.apache.felix.ipojo.xml.parser.XMLMetadataParser;

@@ -89,7 +90,6 @@
      * @param mes : error message.

      */

     private void error(String mes) {

-        System.out.println("An error occurs during the pojoization : " + mes);

         m_errors.add(mes);

     }

 

@@ -98,7 +98,6 @@
      * @param mes : warning message

      */

     public void warn(String mes) {

-        System.out.println("An warning occurs during the pojoization : " + mes);

         m_warnings.add(mes);

     }

 

@@ -356,6 +355,12 @@
                 name += ".class";

                 componentClazzes.add(new ComponentInfo(name, meta[i]));

             }

+            if (meta[i].getName().equalsIgnoreCase("handler") && meta[i].containsAttribute("className")) {

+                String name = meta[i].getAttribute("classname");

+                name = name.replace('.', '/');

+                name += ".class";

+                componentClazzes.add(new ComponentInfo(name, meta[i]));

+            }

         }

         return componentClazzes;

     }

@@ -409,7 +414,7 @@
     private void setImports(Attributes att) {

         Map imports = parseHeader(att.getValue("Import-Package"));

         Map ver = new TreeMap();

-        ver.put("version", "0.7.3");

+        ver.put("version", "0.7.5");

         if (!imports.containsKey("org.apache.felix.ipojo")) {

             imports.put("org.apache.felix.ipojo", ver);

         }

@@ -426,21 +431,6 @@
             verCM.put("version", "1.3");

             imports.put("org.osgi.service.log", verCM);

         }

-        

-

-        // Add handler namespace

-        String[][] namespaces = computeHandlerNamespace();

-        for (int j = 0; j < namespaces.length; j++) {

-            for (int k = 0; k < namespaces[j].length; k++) {

-                if (!namespaces[j][k].equals("")) {

-                    int lastIndex = namespaces[j][k].lastIndexOf('.');

-                    String ns = namespaces[j][k].substring(0, lastIndex);

-                    if (!imports.containsKey(ns)) {

-                        imports.put(ns, new TreeMap());

-                    }

-                }

-            }

-        }

 

         // Add referred imports from the metadata

         for (int i = 0; i < m_referredPackages.size(); i++) {

@@ -467,18 +457,6 @@
     }

 

     /**

-     * Build the list of namespaces used in the metadata. (first-order only). 

-     * @return the list of namespaces [array of component [ array of namespace ] ].

-     */

-    private String[][] computeHandlerNamespace() {

-        String[][] ns = new String[m_metadata.length][];

-        for (int i = 0; i < m_metadata.length; i++) {

-            ns[i] = m_metadata[i].getNamespaces();

-        }

-        return ns;

-    }

-

-    /**

      * Standard OSGi header parser. This parser can handle the format clauses ::= clause ( ',' clause ) + clause ::= name ( ';' name ) (';' key '=' value )

      * This is mapped to a Map { name => Map { attr|directive => value } }

      * 

@@ -588,7 +566,7 @@
             stream.close();

 

         } catch (MalformedURLException e) {

-            error("Malformed Mtadata URL for " + path);

+            error("Malformed Metadata URL for " + path);

             return null;

         } catch (IOException e) {

             error("Cannot open the file : " + path);

@@ -619,19 +597,19 @@
     

     /**

      * Get packages referenced by composite.

-     * 

      * @return the list of referenced packages.

      */

     private List getReferredPackages() {

         List referred = new ArrayList();

         for (int i = 0; i < m_metadata.length; i++) {

             if (m_metadata[i].getName().equalsIgnoreCase("composite")) {

-                for (int j = 0; j < m_metadata[i].getElements().length; j++) {

-                    if (m_metadata[i].getElements()[j].containsAttribute("specification")) {

-                        String p = m_metadata[i].getElements()[j].getAttribute("specification");

-                        int last = p.lastIndexOf('.');

+                Element[] elems = m_metadata[i].getElements();

+                for (int j = 0; j < elems.length; j++) {

+                    String att = elems[j].getAttribute("specification");

+                    if (att != null) {

+                        int last = att.lastIndexOf('.');

                         if (last != -1) {

-                            referred.add(p.substring(0, last));

+                            referred.add(att.substring(0, last));

                         }

                     }

                 }

@@ -654,16 +632,19 @@
             result = actual + element.getNameSpace() + ":" + element.getName() + " { ";

         }

 

-        for (int i = 0; i < element.getAttributes().length; i++) {

-            if (element.getAttributes()[i].getNameSpace().equals("")) {

-                result = result + "$" + element.getAttributes()[i].getName() + "=\"" + element.getAttributes()[i].getValue() + "\" ";

+        Attribute[] atts = element.getAttributes();

+        for (int i = 0; i < atts.length; i++) {

+            Attribute current = (Attribute) atts[i];

+            if (current.getNameSpace().equals("")) {

+                result = result + "$" + current.getName() + "=\"" + current.getValue() + "\" ";

             } else {

-                result = result + "$" + element.getAttributes()[i].getNameSpace() + ":" + element.getAttributes()[i].getName() + "=\"" + element.getAttributes()[i].getValue() + "\" ";

+                result = result + "$" + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\" ";

             }

         }

 

-        for (int i = 0; i < element.getElements().length; i++) {

-            result = buildManifestMetadata(element.getElements()[i], result);

+        Element[] elems = element.getElements();

+        for (int i = 0; i < elems.length; i++) {

+            result = buildManifestMetadata(elems[i], result);

         }

 

         return result + "}";

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
index 04d7a3f..906ea05 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
@@ -41,13 +41,13 @@
      * Get component type metadata. (both component and composite)

      * 

      * @return a components metadata

-     * @throws ParseException

-     *             when an error occurs in the xml parsing

+     * @throws ParseException :  occurs in the xml parsing

      */

     public Element[] getComponentsMetadata() throws ParseException {

         Element[] comp = m_elements[0].getElements("Component");

         Element[] compo = m_elements[0].getElements("Composite");

-        Element[] metadata = new Element[comp.length + compo.length];

+        Element[] handl = m_elements[0].getElements("Handler");

+        Element[] metadata = new Element[comp.length + compo.length + handl.length];

         int l = 0;

         for (int i = 0; i < comp.length; i++) {

             metadata[l] = comp[i];

@@ -57,6 +57,10 @@
             metadata[l] = compo[i];

             l++;

         }

+        for (int i = 0; i < handl.length; i++) {

+            metadata[l] = handl[i];

+            l++;

+        }

         return metadata;

     }

 

@@ -70,7 +74,8 @@
         Element[] comp = m_elements[0].getElements("Component");

         Element[] compo = m_elements[0].getElements("Composite");

         Element[] conf = m_elements[0].getElements("Instance");

-        Element[] metadata = new Element[comp.length + conf.length + compo.length];

+        Element[] handl = m_elements[0].getElements("Handler");

+        Element[] metadata = new Element[comp.length + conf.length + compo.length + handl.length];

         int l = 0;

         for (int i = 0; i < comp.length; i++) {

             metadata[l] = comp[i];

@@ -84,6 +89,10 @@
             metadata[l] = conf[i];

             l++;

         }

+        for (int i = 0; i < handl.length; i++) {

+            metadata[l] = handl[i];

+            l++;

+        }

         return metadata;

     }

 

@@ -123,12 +132,12 @@
         // Get the last element of the list

         Element lastElement = removeLastElement();

 

-        // Check if the name is consitent with the name of this end tag

-        if (!lastElement.getName().equalsIgnoreCase(qName) && !lastElement.getNameSpace().equals(namespaceURI)) {

+        // Check if the name is consistent with the name of this end tag

+        if (!lastElement.getName().equalsIgnoreCase(qName) && !lastElement.getNameSpace().equalsIgnoreCase(namespaceURI)) {

             throw new SAXException("Parse error when ending an element : " + qName + " [" + namespaceURI + "]");

         }

 

-        // The name is consitent

+        // The name is consistent

         // Add this element last element with if it is not the root

         if (m_elements.length != 0) {

             Element newQueue = m_elements[m_elements.length - 1];

diff --git a/ipojo/metadata/pom.xml b/ipojo/metadata/pom.xml
index 5b40d7e..177115d 100644
--- a/ipojo/metadata/pom.xml
+++ b/ipojo/metadata/pom.xml
@@ -8,7 +8,7 @@
   <modelVersion>4.0.0</modelVersion>
   <artifactId>org.apache.felix.ipojo.metadata</artifactId>
   <packaging>bundle</packaging>
-  <version>0.7.3-SNAPSHOT</version>
+  <version>0.7.5-SNAPSHOT</version>
   <name>Apache Felix iPOJO Metadata</name>
   <build>
   <plugins>
diff --git a/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java b/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
index f17b6ce..25aab36 100644
--- a/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
+++ b/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
@@ -18,6 +18,14 @@
  */
 package org.apache.felix.ipojo.metadata;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * Element.
  * 
@@ -36,14 +44,18 @@
     private String m_nameSpace;
 
     /**
-     * List of the attributes of the element.
+     * Map of attributes of the element.
+     * The map key is the qualified name of the attribute (ns:name)
+     * The value is the attribute object.
      */
-    private Attribute[] m_attributes = new Attribute[0];
+    private Map m_attributes = new HashMap();
 
     /**
-     * List of the sub-element of the element.
+     * Map of the sub-element of the element.
+     * The map key is the element qualified name (ns:name).
+     * The value is the array of element of this name.
      */
-    private Element[] m_elements = new Element[0];
+    private Map m_elements = new HashMap();
 
     /**
      * Constructor.
@@ -52,7 +64,7 @@
      */
     public Element(String name, String ns) {
         m_name = name.toLowerCase();
-        m_nameSpace = ns;
+        m_nameSpace = ns.toLowerCase();
     }
 
     /**
@@ -60,7 +72,16 @@
      * @return the sub elements
      */
     public Element[] getElements() {
-        return m_elements;
+        Collection col = m_elements.values();
+        Iterator it = col.iterator();
+        List list = new ArrayList();
+        while (it.hasNext()) {
+            Element[] v = (Element[]) it.next();
+            for (int i = 0; i < v.length; i++) {
+                list.add(v[i]);
+            }
+        }
+        return (Element[]) list.toArray(new Element[0]);
     }
 
     /**
@@ -68,7 +89,7 @@
      * @return the attributes
      */
     public Attribute[] getAttributes() {
-        return m_attributes;
+        return (Attribute[]) m_attributes.values().toArray(new Attribute[0]);
     }
 
     /**
@@ -94,13 +115,12 @@
      */
     public String getAttribute(String name) {
         name = name.toLowerCase();
-        for (int i = 0; i < m_attributes.length; i++) {
-            if (m_attributes[i].getName().equals(name)) {
-                return m_attributes[i].getValue();
-            }
+        Attribute att = (Attribute) m_attributes.get(name);
+        if (att == null) {
+            return null;
+        } else {
+            return att.getValue();
         }
-        System.err.println("[Error in Metadata] The attribute " + name + " does not exist in " + m_name + " [" + m_nameSpace + "]");
-        return null;
     }
 
     /**
@@ -110,14 +130,20 @@
      * @return the String value of the attribute, or null if the attribute is not found.
      */
     public String getAttribute(String name, String ns) {
-        name = name.toLowerCase();
-        for (int i = 0; i < m_attributes.length; i++) {
-            if (m_attributes[i].getName().equals(name) && m_attributes[i].getNameSpace().equals(ns)) {
-                return m_attributes[i].getValue();
-            }
+        name = ns.toLowerCase() + ":" + name.toLowerCase();
+        return getAttribute(name);
+    }
+    
+    /**
+     * Get the qualified name of the current element.
+     * @return the qualified name of the current element.
+     */
+    private String getQualifiedName() {
+        if (m_nameSpace.equals("")) {
+            return m_name;
+        } else {
+            return m_nameSpace + ":" + m_name;
         }
-        System.err.println("[Error in Metadata] The attribute " + name + "[" + ns + "] does not exist in " + m_name + " [" + m_nameSpace + "]");
-        return null;
     }
 
     /**
@@ -125,36 +151,14 @@
      * @param elem : the element to add
      */
     public void addElement(Element elem) {
-        for (int i = 0; (m_elements != null) && (i < m_elements.length); i++) {
-            if (m_elements[i] == elem) {
-                return;
-            }
-        }
-
-        if (m_elements != null) {
-            Element[] newElementsList = new Element[m_elements.length + 1];
-            System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
-            newElementsList[m_elements.length] = elem;
-            m_elements = newElementsList;
+        Element[] array = (Element[]) m_elements.get(elem.getQualifiedName());
+        if (array == null) {
+            m_elements.put(elem.getQualifiedName(), new Element[] {elem});
         } else {
-            m_elements = new Element[] { elem };
-        }
-    }
-
-    /**
-     * Add an element to the given list.
-     * @param list : the input list.
-     * @param elem : the element to add.
-     * @return the returned element list.
-     */
-    private static Element[] addElement(Element[] list, Element elem) {
-        if (list != null) {
-            Element[] newElementsList = new Element[list.length + 1];
-            System.arraycopy(list, 0, newElementsList, 0, list.length);
-            newElementsList[list.length] = elem;
-            return newElementsList;
-        } else {
-            return new Element[] { elem };
+            Element[] newElementsList = new Element[array.length + 1];
+            System.arraycopy(array, 0, newElementsList, 0, array.length);
+            newElementsList[array.length] = elem;
+            m_elements.put(elem.getQualifiedName(), newElementsList);
         }
     }
 
@@ -163,24 +167,29 @@
      * @param elem : the element to remove
      */
     public void removeElement(Element elem) {
-        int idx = -1;
-        for (int i = 0; i < m_elements.length; i++) {
-            if (m_elements[i] == elem) {
-                idx = i;
-                break;
-            }
-        }
-
-        if (idx >= 0) {
-            if ((m_elements.length - 1) == 0) {
-                m_elements = new Element[0];
-            } else {
-                Element[] newElementsList = new Element[m_elements.length - 1];
-                System.arraycopy(m_elements, 0, newElementsList, 0, idx);
-                if (idx < newElementsList.length) {
-                    System.arraycopy(m_elements, idx + 1, newElementsList, idx, newElementsList.length - idx);
+        Element[] array = (Element[]) m_elements.get(elem.getQualifiedName());
+        if (array == null) {
+            return;
+        } else {
+            int idx = -1;
+            for (int i = 0; i < array.length; i++) {
+                if (array[i] == elem) {
+                    idx = i;
+                    break;
                 }
-                m_elements = newElementsList;
+            }
+
+            if (idx >= 0) {
+                if ((array.length - 1) == 0) {
+                    m_elements.remove(elem.getQualifiedName());
+                } else {
+                    Element[] newElementsList = new Element[array.length - 1];
+                    System.arraycopy(array, 0, newElementsList, 0, idx);
+                    if (idx < newElementsList.length) {
+                        System.arraycopy(array, idx + 1, newElementsList, idx, newElementsList.length - idx);
+                    }
+                    m_elements.put(elem.getQualifiedName(), newElementsList); // Update the stored list.
+                }
             }
         }
     }
@@ -190,20 +199,11 @@
      * @param att : the attribute to add
      */
     public void addAttribute(Attribute att) {
-        for (int i = 0; (m_attributes != null) && (i < m_attributes.length); i++) {
-            if (m_attributes[i] == att) {
-                return;
-            }
+        String name = att.getName().toLowerCase();
+        if (!att.getNameSpace().equals("")) {
+            name = att.getNameSpace().toLowerCase() + ":" + name;
         }
-
-        if (m_attributes != null) {
-            Attribute[] newAttributesList = new Attribute[m_attributes.length + 1];
-            System.arraycopy(m_attributes, 0, newAttributesList, 0, m_attributes.length);
-            newAttributesList[m_attributes.length] = att;
-            m_attributes = newAttributesList;
-        } else {
-            m_attributes = new Attribute[] { att };
-        }
+        m_attributes.put(name, att);
     }
 
     /**
@@ -211,26 +211,11 @@
      * @param att : the attribute to remove
      */
     public void removeAttribute(Attribute att) {
-        int idx = -1;
-        for (int i = 0; i < m_attributes.length; i++) {
-            if (m_attributes[i] == att) {
-                idx = i;
-                break;
-            }
+        String name = att.getName();
+        if (!att.getNameSpace().equals("")) {
+            name = att.getNameSpace() + ":" + name;
         }
-
-        if (idx >= 0) {
-            if ((m_attributes.length - 1) == 0) {
-                m_attributes = new Attribute[0];
-            } else {
-                Attribute[] newAttributesList = new Attribute[m_attributes.length - 1];
-                System.arraycopy(m_attributes, 0, newAttributesList, 0, idx);
-                if (idx < newAttributesList.length) {
-                    System.arraycopy(m_attributes, idx + 1, newAttributesList, idx, newAttributesList.length - idx);
-                }
-                m_attributes = newAttributesList;
-            }
-        }
+        m_attributes.remove(name);
     }
 
     /**
@@ -240,13 +225,12 @@
      */
     public Element[] getElements(String name) {
         name = name.toLowerCase();
-        Element[] list = new Element[0];
-        for (int i = 0; i < m_elements.length; i++) {
-            if (m_elements[i].getName().equalsIgnoreCase(name) && m_elements[i].getNameSpace().equals("")) {
-                list = Element.addElement(list, m_elements[i]);
-            }
+        Element[] elems = (Element[]) m_elements.get(name);
+        if (elems == null) {
+            return new Element[0];
+        } else {
+            return elems;
         }
-        return list;
     }
 
     /**
@@ -256,46 +240,34 @@
      * @return the resulting element array (empty if the search failed)
      */
     public Element[] getElements(String name, String ns) {
-        name = name.toLowerCase();
-        Element[] list = new Element[0];
-        for (int i = 0; i < m_elements.length; i++) {
-            if (m_elements[i].getName().equals(name) && m_elements[i].getNameSpace().equals(ns)) {
-                list = Element.addElement(list, m_elements[i]);
-            }
+        if (ns == null || ns.equals("")) {
+            return getElements(name);
         }
-        return list;
+        name = ns + ":" + name;
+        return getElements(name);
     }
 
     /**
-     * Is the element contains a sub-element of the type given in parameter. This method does not manage the namespace
+     * Is the element contains a sub-element of the type given in parameter.
      * @param name : type of the element to check.
      * @return true if the element contains an element of the type "name"
      */
     public boolean containsElement(String name) {
         name = name.toLowerCase();
-        for (int i = 0; i < m_elements.length; i++) {
-            if (m_elements[i].getName().equals(name)) {
-                return true;
-            }
-        }
-        return false;
+        return m_elements.containsKey(name);
     }
 
     /**
-     * Is the element contains a sub-element of the type given in parameter. This method does not manage the namespace
+     * Is the element contains a sub-element of the type given in parameter. 
      * @param name : type of the element to check.
      * @param ns : the namespace of the element to check.
      * @return true if the element contains an element of the type "name"
      */
     public boolean containsElement(String name, String ns) {
-        name = name.toLowerCase();
-        ns = ns.toLowerCase();
-        for (int i = 0; i < m_elements.length; i++) {
-            if (m_elements[i].getName().equals(name) && m_elements[i].getNameSpace().equals(ns)) {
-                return true;
-            }
+        if (ns != null && !ns.equals("")) {
+            name = ns + ":" + name;
         }
-        return false;
+        return containsElement(name);
     }
 
     /**
@@ -304,57 +276,9 @@
      * @return true if the element contains an attribute of the type "name"
      */
     public boolean containsAttribute(String name) {
-        name = name.toLowerCase();
-        for (int i = 0; i < m_attributes.length; i++) {
-            if (m_attributes[i].getName().equals(name)) {
-                return true;
-            }
-        }
-        return false;
+        return m_attributes.containsKey(name.toLowerCase());
     }
-
-    /**
-     * Get used namespace.
-     * @return the first-order namespaces list of the current element. First-order namespace are namespace of the element attribute and namespaces of its direct sub-element.
-     */
-    public String[] getNamespaces() {
-        String[] ns = new String[0];
-
-        // Look for each direct sub-element
-        for (int i = 0; i < m_elements.length; i++) {
-            boolean found = false;
-            for (int j = 0; !found && j < ns.length; j++) {
-                if (ns[j].equals(m_elements[i].getNameSpace())) {
-                    found = true;
-                }
-            }
-            if (!found) {
-                String[] newNSList = new String[ns.length + 1];
-                System.arraycopy(ns, 0, newNSList, 0, ns.length);
-                newNSList[ns.length] = m_elements[i].getNameSpace();
-                ns = newNSList;
-            }
-        }
-
-        // Look for each attribute
-        for (int i = 0; i < m_attributes.length; i++) {
-            boolean found = false;
-            for (int j = 0; !found && j < ns.length; j++) {
-                if (ns[j].equals(m_attributes[i].getNameSpace())) {
-                    found = true;
-                }
-            }
-            if (!found) {
-                String[] newNSList = new String[ns.length + 1];
-                System.arraycopy(ns, 0, newNSList, 0, ns.length);
-                newNSList[ns.length] = m_attributes[i].getNameSpace();
-                ns = newNSList;
-            }
-        }
-
-        return ns;
-    }
-
+    
     /**
      * Get the XML form of this element.
      * @return the XML snippet representing this element.
@@ -376,29 +300,36 @@
             tabs += "\t";
         }
 
-        if (m_nameSpace.equals("")) {
+        if ("".equals(m_nameSpace)) {
             xml = tabs + "<" + m_name;
         } else {
             xml = tabs + "<" + m_nameSpace + ":" + m_name;
         }
 
-        for (int i = 0; i < m_attributes.length; i++) {
-            Attribute current = m_attributes[i];
-            if (current.getNameSpace().equals("")) {
+        Set keys = m_attributes.keySet();
+        Iterator it = keys.iterator();
+        while (it.hasNext()) {
+            Attribute current = (Attribute) m_attributes.get(it.next());
+            if ("".equals(current.getNameSpace())) {
                 xml += " " + current.getName() + "=\"" + current.getValue() + "\"";
             } else {
                 xml += " " + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\"";
             }
         }
 
-        if (m_elements.length == 0) {
+        if (m_elements.size() == 0) {
             xml += "/>";
             return xml;
         } else {
             xml += ">";
-            for (int i = 0; i < m_elements.length; i++) {
-                xml += "\n";
-                xml += m_elements[i].toXMLString(indent + 1);
+            keys = m_elements.keySet();
+            it = keys.iterator();
+            while (it.hasNext()) {
+                Element[] e = (Element[]) m_elements.get(it.next());
+                for (int i = 0; i < e.length; i++) {
+                    xml += "\n";
+                    xml += e[i].toXMLString(indent + 1);
+                }
             }
             xml += "\n" + tabs + "</" + m_name + ">";
             return xml;
@@ -427,27 +358,34 @@
             tabs += "\t";
         }
 
-        if (m_nameSpace.equals("")) {
+        if ("".equals(m_nameSpace)) {
             xml = tabs + m_name;
         } else {
             xml = tabs + m_nameSpace + ":" + m_name;
         }
 
-        for (int i = 0; i < m_attributes.length; i++) {
-            Attribute current = m_attributes[i];
-            if (current.getNameSpace().equals("")) {
+        Set keys = m_attributes.keySet();
+        Iterator it = keys.iterator();
+        while (it.hasNext()) {
+            Attribute current = (Attribute) m_attributes.get(it.next());
+            if ("".equals(current.getNameSpace())) {
                 xml += " " + current.getName() + "=\"" + current.getValue() + "\"";
             } else {
                 xml += " " + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\"";
             }
         }
 
-        if (m_elements.length == 0) {
+        if (m_elements.size() == 0) {
             return xml;
         } else {
-            for (int i = 0; i < m_elements.length; i++) {
-                xml += "\n";
-                xml += m_elements[i].toString(indent + 1);
+            keys = m_elements.keySet();
+            it = keys.iterator();
+            while (it.hasNext()) {
+                Element[] e = (Element[]) m_elements.get(it.next());
+                for (int i = 0; i < e.length; i++) {
+                    xml += "\n";
+                    xml += e[i].toString(indent + 1);
+                }
             }
             return xml;
         }
diff --git a/ipojo/plugin/pom.xml b/ipojo/plugin/pom.xml
index 6e1579f..c222ca9 100644
--- a/ipojo/plugin/pom.xml
+++ b/ipojo/plugin/pom.xml
@@ -7,7 +7,7 @@
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>org.apache.felix.ipojo.plugin</artifactId>
-  <version>0.7.3-SNAPSHOT</version>
+  <version>0.7.5-SNAPSHOT</version>
   <name>Apache Felix iPOJO Maven Plugin</name>
   <packaging>maven-plugin</packaging>
   <dependencies>
@@ -44,7 +44,7 @@
     <dependency>
       <groupId>${pom.groupId}</groupId>
       <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
-      <version>0.7.3-SNAPSHOT</version>
+      <version>0.7.5-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>