diff --git a/ipojo/core/pom.xml b/ipojo/core/pom.xml
index 813548b..c7ef593 100644
--- a/ipojo/core/pom.xml
+++ b/ipojo/core/pom.xml
@@ -1,118 +1,125 @@
 <!--
- 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.
+	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.
 -->
 <project>
-  <parent>
-    <groupId>org.apache.felix</groupId>
-    <artifactId>felix</artifactId>
-    <version>1.0.2</version>
-    <relativePath>../../pom/pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <packaging>bundle</packaging>
-  <name>Apache Felix iPOJO</name>
-  <artifactId>org.apache.felix.ipojo</artifactId>
-  <version>0.7.5-SNAPSHOT</version>
-  <dependencies>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <version>1.1.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.osgi.compendium</artifactId>
-      <version>1.0.0</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
-      <version>0.7.5-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
-      <version>0.7.5-SNAPSHOT</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.4.0</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>          
-            <Bundle-Name>iPOJO</Bundle-Name>
-            <Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>
-            <Bundle-Description> iPOJO </Bundle-Description>
-            <Bundle-Activator>org.apache.felix.ipojo.Extender</Bundle-Activator>
-            <Import-Package>
-              org.osgi.framework, 
-              org.osgi.service.cm,
-              org.osgi.service.log,
-			  !org.objectweb.asm*
-            </Import-Package>
-            <Private-Package>
-            	org.apache.felix.ipojo.manipulation,
-    			org.apache.felix.ipojo.composite.architecture,
-    			org.apache.felix.ipojo.composite.service*,
-    			org.apache.felix.ipojo.composite.instance,
-    			org.apache.felix.ipojo.handlers.architecture,
-    			org.apache.felix.ipojo.handlers.configuration,
-    			org.apache.felix.ipojo.handlers.dependency.nullable,
-              	org.apache.felix.ipojo.handlers.lifecycle.callback,
-              	org.apache.felix.ipojo.handlers.lifecycle.controller,
-              	org.objectweb.asm*;-split-package:=merge-first
-            </Private-Package>
-            <Export-Package>
-              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>maven-ipojo-plugin</artifactId>
-              <version>${pom.version}</version>
-		  <executions>
-          	<execution>
-            	<goals>
-	              <goal>ipojo-bundle</goal>
-               </goals>
-            <configuration>
-   				<metadata>metadata.xml</metadata>
-   				<ignoreAnnotations>true</ignoreAnnotations>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+	<parent>
+		<artifactId>iPOJO</artifactId>
+		<groupId>org.apache.felix</groupId>
+		<version>0.7.6-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<packaging>bundle</packaging>
+	<name>Apache Felix iPOJO</name>
+	<artifactId>org.apache.felix.ipojo</artifactId>
+	<dependencies>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.osgi.core</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.osgi.compendium</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>
+			<version>0.7.6-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
+			<version>0.7.6-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<version>1.4.0</version>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Bundle-Name>iPOJO</Bundle-Name>
+						<Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>
+						<Bundle-Description>
+							iPOJO Core Framework
+						</Bundle-Description>
+						<Bundle-Activator>
+							org.apache.felix.ipojo.Extender
+						</Bundle-Activator>
+						<IPOJO-Extension>
+							component:org.apache.felix.ipojo.ComponentFactory,
+							handler:org.apache.felix.ipojo.HandlerFactory
+						</IPOJO-Extension>
+						<Import-Package>
+							org.osgi.framework, org.osgi.service.cm,
+							org.osgi.service.log
+						</Import-Package>
+						<Private-Package>
+							org.apache.felix.ipojo.handlers.architecture,
+							org.apache.felix.ipojo.handlers.configuration,
+							org.apache.felix.ipojo.handlers.lifecycle.callback,
+							org.apache.felix.ipojo.handlers.lifecycle.controller
+						</Private-Package>
+						<Export-Package>
+							org.apache.felix.ipojo; version="0.7.6",
+							org.apache.felix.ipojo.metadata;
+							version="0.7.6",
+							org.apache.felix.ipojo.architecture;
+							version="0.7.6",
+							org.apache.felix.ipojo.parser;
+							version="0.7.6",
+							org.apache.felix.ipojo.util;
+							version="0.7.6",
+							org.apache.felix.ipojo.handlers.dependency;
+							version="0.7.6",
+							org.apache.felix.ipojo.handlers.providedservice;
+							version="0.7.6",
+							org.apache.felix.ipojo.context;
+							version="0.7.6", 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>maven-ipojo-plugin</artifactId>
+				<version>${pom.version}</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>ipojo-bundle</goal>
+						</goals>
+						<configuration>
+							<metadata>metadata.xml</metadata>
+							<ignoreAnnotations>true</ignoreAnnotations>
+						</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 d5ff230..1c62ecf 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
@@ -21,27 +21,22 @@
 import java.net.URL;
 import java.security.ProtectionDomain;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.PojoMetadata;
 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;
 
 /**
  * The component factory manages component instance objects. This management
@@ -50,379 +45,114 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ComponentFactory implements Factory, ManagedServiceFactory, TrackerCustomizer {
-
-    /**
-     * List of the managed instance name. This list is shared by all factories.
-     */
-    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. instance names) of the created instance
-     */
-    protected Map m_componentInstances = new HashMap();
-    
-    /**
-     * Component Type provided by this factory.
-     */
-    protected Element m_componentMetadata;
-    
-    /**
-     * The bundle context reference.
-     */
-    protected BundleContext m_context = null;    
-    
-    /**
-     * Factory Name. Could be the component class name if the
-     * factory name is not set.
-     */
-    protected String m_factoryName;
-
-    /**
-     * List of required handler.
-     */
-    protected List m_handlerIdentifiers = new ArrayList();
-
-    /**
-     * List of listeners.
-     */
-    protected List m_listeners = new ArrayList(5);
-    
-    /**
-     * Logger for the factory (and all component instance).
-     */
-    protected Logger m_logger;
-
-    /**
-     * Factory state.
-     */
-    protected int m_state = Factory.INVALID;
+public class ComponentFactory extends IPojoFactory implements TrackerCustomizer {
 
     /**
      * Tracker used to track required handler factories.
      */
     protected Tracker m_tracker;
-    
-    /**
-     * Is the factory public (expose as a service). 
-     */
-    protected boolean m_isPublic;
 
     /**
      * Class loader to delegate loading.
      */
     private FactoryClassloader m_classLoader = null;
-    
+
     /**
      * Component Implementation class.
      */
     private byte[] m_clazz = null;
-    
+
     /**
      * Component Implementation Class Name.
      */
-    private String m_componentClassName = null;
-    
+    private String m_classname = null;
+
     /**
-     * Index used to generate instance name if not set.
+     * Manipulation Metadata of the internal POJO.
      */
-    private long m_index = 0;
-    
-    /**
-     * Service Registration of this factory (Factory & ManagedServiceFactory).
-     */
-    private ServiceRegistration m_sr;
-    
+    private PojoMetadata m_manipulation = null;
+
     /**
      * Create a instance manager factory. The class is given in parameter. The
      * component type is not a composite.
-     * @param bc : bundle context
+     * @param context : bundle context
      * @param clazz : the component class
-     * @param cm : metadata of the component
+     * @param element : metadata of the component
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
      */
-    public ComponentFactory(BundleContext bc, byte[] clazz, Element cm) {
-        this(bc, cm);
+    public ComponentFactory(BundleContext context, byte[] clazz, Element element) throws ConfigurationException {
+        this(context, element);
         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 (! check(cm)) {
-            return;
-        }
-        
-        computeFactoryName();        
-        m_logger = new Logger(m_context, m_factoryName, Logger.WARNING);
-        
-        String fac = cm.getAttribute("factory");
-        m_isPublic = fac == null || ! fac.equalsIgnoreCase("false");
-        
-        computeRequiredHandlers();
-        
-    }
-    
-    /**
-     * Add a factory listener.
-     * @param l : the factory listener to add
-     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
-     */
-    public void addFactoryStateListener(FactoryStateListener l) {
-        synchronized (m_listeners) {
-            m_listeners.add(l);
-        }
-        // TODO do we need to notify the actual state of the factory to the new listener ?
-    }
 
     /**
-     * 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)
+     * Create a instance manager factory.
+     * @param context : bundle context
+     * @param element : metadata of the component to create
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
      */
-    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)) {
-                int oldP = hi.m_level;
-                hi.setReference(reference);
-                // If the priority has changed, sort the list.
-                if (oldP != hi.m_level) {
-                    Collections.sort(m_handlerIdentifiers);
-                }
-                return true;
-            }
-        }
-        return false;
+    public ComponentFactory(BundleContext context, Element element) throws ConfigurationException {
+        super(context, element);
+        check(element); // NOPMD. This invocation is normal.
     }
-    
-    /**
-     * A matching service has been added to the tracker, we can no compute the factory state.
-     * @param reference : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        if (m_state == INVALID) {
-            try {
-                computeFactoryState();
-            } catch (org.apache.felix.ipojo.ConfigurationException e) {
-                m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
-                stop();
-            }
-        }
+
+    public ComponentTypeDescription getComponentTypeDescription() {
+        return new PrimitiveTypeDescription(this);
     }
 
     /**
      * 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
+     * @param element : the metadata
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
      */
-    public boolean check(Element cm) {
-        m_componentClassName = cm.getAttribute("className");
-        if (m_componentClassName == null) {
-            System.err.println("A component needs a class name : " + cm);
-            return false;
-        } else {
-            return true;
-        }
+    public void check(Element element) throws ConfigurationException {
+        m_classname = element.getAttribute("className");
+        if (m_classname == null) { throw new ConfigurationException("A component needs a class name : " + element); }
+    }
+
+    public String getClassName() {
+        return m_classname;
     }
 
     /**
-     * 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)
+     * Create a primitive instance.
+     * @param config : instance configuration
+     * @param context : service context.
+     * @param handlers : handler to use
+     * @return the created instance
+     * @throws org.apache.felix.ipojo.ConfigurationException : if the configuration process failed.
+     * @see org.apache.felix.ipojo.IPojoFactory#createInstance(java.util.Dictionary, org.apache.felix.ipojo.IPojoContext, org.apache.felix.ipojo.HandlerManager[])
      */
-    public 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 synchronized ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {        
-        if (configuration == null) {
-            configuration = new Properties();
-        }
-        
+    public ComponentInstance createInstance(Dictionary config, IPojoContext context, HandlerManager[] handlers) throws org.apache.felix.ipojo.ConfigurationException {
+        InstanceManager instance = new InstanceManager(this, context, handlers);
+        instance.configure(m_componentMetadata, config);
         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());
+            instance.start();
+            return instance;
+        } catch (IllegalStateException e) {
+            // An exception occurs during the start method.
+            m_logger.log(Logger.ERROR, e.getMessage(), e);
+            throw new ConfigurationException(e.getMessage());
         }
 
-        
-        String n = null;
-        if (configuration.get("name") != null) {
-            n = (String) configuration.get("name");
-            if (m_instancesName.contains(n)) {
-                throw new UnacceptableConfiguration("Name already used : " + n);
-            }
-        } else {
-            n = generateName();
-            configuration.put("name", n);
-        }
-        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[m_handlerIdentifiers.size()]));
-        try {
-            instance.configure(m_componentMetadata, configuration);
-        } catch (org.apache.felix.ipojo.ConfigurationException e) {
-            throw new org.apache.felix.ipojo.ConfigurationException(e.getMessage(), m_factoryName);
-        }
-
-        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 clazz : byte array of the class
      * @param domain : protection domain of the class
      * @return the defined class object
      */
-    public Class defineClass(String name, byte[] b, ProtectionDomain domain) {
+    public Class defineClass(String name, byte[] clazz, ProtectionDomain domain) {
         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();
-        }
+        return m_classLoader.defineClass(name, clazz, domain);
     }
 
     /**
-     * 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 " + m_factoryName, ""); }
-        return m_componentDesc.getDescription();
-    }
-    
-    /**
-     * Get the logger used by instances of he current factory.
-     * @return the factory logger.
-     */
-    public Logger getLogger() {
-        return m_logger;
-    }
-    
-    /**
-     * 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() {
-        return m_factoryName;
-    }
-
-    /**
-     * 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;
-    }
-    
-    public String getClassName() {
-        return m_componentClassName;
-    }
-
-    public int getState() {
-        return m_state;
-    }
-    
-    /**
      * Return the URL of a resource.
      * @param resName : resource name
      * @return the URL of the resource
@@ -432,24 +162,6 @@
     }
 
     /**
-     * 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
@@ -457,22 +169,144 @@
      * @throws ClassNotFoundException : happen when the class is not found
      */
     public Class loadClass(String className) throws ClassNotFoundException {
-        if (m_clazz != null && className.equals(m_componentClassName)) {
+        if (m_clazz != null && className.equals(m_classname)) {
             // 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_classLoader.defineClass(m_classname, m_clazz, null);
         }
         return m_context.getBundle().loadClass(className);
     }
 
     /**
+     * Start the factory.
+     */
+    public synchronized void starting() {
+        if (m_requiredHandlers.size() != 0) {
+            try {
+                String filter = "(&(" + 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());
+                stop();
+            }
+        }
+    }
+
+    /**
+     * Stop all the instance managers.
+     */
+    public synchronized void stopping() {
+        m_tracker.close();
+        m_tracker = null;
+        m_classLoader = null;
+        m_clazz = null;
+    }
+
+    /**
+     * Compute the factory name.
+     * @return the factory name.
+     */
+    public String getFactoryName() {
+        String name = m_componentMetadata.getAttribute("name");
+        if (name == null) { // No factory name, try with factory attribute
+            name = m_componentMetadata.getAttribute("factory");
+            if (name == null || name.equalsIgnoreCase("true") || name.equalsIgnoreCase("false")) { // Avoid boolean case
+                name = m_componentMetadata.getAttribute("className");
+            }
+        }
+        return name;
+    }
+
+    /**
+     * Compute required handlers.
+     * @return the required handler list.
+     */
+    public List getRequiredHandlerList() {
+        List list = new ArrayList();
+        Element[] elems = m_componentMetadata.getElements();
+        for (int i = 0; i < elems.length; i++) {
+            Element current = elems[i];
+            if (!"manipulation".equals(current.getName())) {
+                RequiredHandler req = new RequiredHandler(current.getName(), current.getNameSpace());
+                if (!list.contains(req)) {
+                    list.add(req);
+                }
+            }
+        }
+
+        // Add architecture if architecture != 'false'
+        String arch = m_componentMetadata.getAttribute("architecture");
+        if (arch == null || arch.equalsIgnoreCase("true")) {
+            list.add(new RequiredHandler("architecture", null));
+        }
+
+        // Add lifecycle callback if immediate = true
+        RequiredHandler reqCallback = new RequiredHandler("callback", null);
+        String imm = m_componentMetadata.getAttribute("immediate");
+        if (!list.contains(reqCallback) && imm != null && imm.equalsIgnoreCase("true")) {
+            list.add(reqCallback);
+        }
+
+        return list;
+    }
+
+    /**
+     * 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)
+     */
+    public boolean addingService(ServiceReference reference) {
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (req.getReference() == null && match(req, reference)) {
+                int oldP = req.getLevel();
+                req.setReference(reference);
+                // If the priority has changed, sort the list.
+                if (oldP != req.getLevel()) {
+                    Collections.sort(m_requiredHandlers);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * A matching service has been added to the tracker, we can no compute the factory state.
+     * @param reference : added reference.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference reference) {
+        if (m_state == INVALID) {
+            computeFactoryState();
+        }
+    }
+
+    /**
+     * 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
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (reference.equals(req.getReference())) {
+                req.unRef(); // This method will unget the service.
+                computeFactoryState();
+                return; // The factory can be used only once.
+            }
+        }
+    }
+
+    /**
      * A used handler factory is modified.
      * @param reference : the service reference
      * @param service : the Factory object (if already get)
@@ -483,561 +317,15 @@
     }
 
     /**
-     * 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)
+     * Returns manipulation metadata of this component type.
+     * The returned object is computed at the first call and then is cached.
+     * @return manipulation metadata of this component type.
      */
-    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");
+    public PojoMetadata getPojoMetadata() {
+        if (m_manipulation == null) {
+            m_manipulation = new PojoMetadata(m_componentMetadata);
         }
-        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
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            if (reference.equals(hi.getReference())) {
-                hi.unRef(); // This method will unget the service.
-                try {
-                    computeFactoryState();
-                } catch (org.apache.felix.ipojo.ConfigurationException e) {
-                    m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
-                    stop();
-                }
-                return; // The factory can be used only once.
-            }
-        }
-    }
-
-    /**
-     * 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;
-        } 
-        
-        if (m_handlerIdentifiers.size() != 0) {
-            try {
-                String filter = "(&(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")"
-                        + "(" + 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());
-                stop();
-                return;
-            }
-        }
-            
-        try {
-            computeFactoryState();
-        } catch (org.apache.felix.ipojo.ConfigurationException e) {
-            m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
-            stop();
-            return;
-        }
-
-        if (m_isPublic) {        
-            // 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) m_handlerIdentifiers.get(i)).unRef();
-        }
-        
-        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 {
-        if (m_state == Factory.INVALID) {
-            throw new MissingHandlerException(getMissingHandlers());
-        }
-        
-        List props = m_componentDesc.getRequiredProperties();
-        for (int i = 0; i < props.size(); i++) {
-            // Failed if the props has no default value and the configuration does not push a value
-            if (conf.get(props.get(i)) == null) {
-                throw new UnacceptableConfiguration("The configuration does not contains the \"" + props.get(i) + "\" 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 {
-        m_componentDesc = new ComponentDescription(this);
-         
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            HandlerManager hm = getHandlerInstance(hi, null);
-            Handler ch =  hm.getHandler();
-            try {
-                ch.setLogger(getLogger());
-                ch.initializeComponentFactory(m_componentDesc, m_componentMetadata);
-                ((Pojo) ch).getComponentInstance().dispose();
-            } catch (org.apache.felix.ipojo.ConfigurationException e) {
-                ((Pojo) ch).getComponentInstance().dispose();
-                throw new org.apache.felix.ipojo.ConfigurationException(e.getMessage(), m_factoryName);
-            }
-        }
-    }
-
-    /**
-     * Compute the factory name.
-     */
-    protected void computeFactoryName() {
-        m_factoryName = m_componentMetadata.getAttribute("name");
-        if (m_factoryName == null) { // No factory name, try with factory attribute
-            m_factoryName = m_componentMetadata.getAttribute("factory");
-            if (m_factoryName == null || m_factoryName.equalsIgnoreCase("true") || m_factoryName.equalsIgnoreCase("false")) { // Avoid boolean case
-                m_factoryName = m_componentMetadata.getAttribute("className");
-            }
-        }
-    }
-    
-    /**
-     * Compute factory state.
-     * @throws org.apache.felix.ipojo.ConfigurationException : occurs when the component type cannot be initialize.
-     */
-    protected void computeFactoryState() throws org.apache.felix.ipojo.ConfigurationException {
-        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) {
-            if (m_state == INVALID) {
-                
-                if (m_componentDesc == null) {
-                    computeDescription();
-                }
-                
-                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;
-            }
-        } else {
-            if (m_state == VALID) {
-                m_state = INVALID;
-                
-                // Notify listeners.
-                for (int i = 0; i < m_listeners.size(); i++) {
-                    ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
-                }
-
-                // Dispose created instances.
-                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.m_name);
-                }
-
-                m_componentInstances.clear();
-
-                // Update service properties TODO : really useful ?
-                if (m_sr != null) {
-                    m_sr.setProperties(getProperties());
-                }
-                
-                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); }
-        }
-        
-        // Add architecture if architecture != 'false'
-        HandlerIdentifier hi = new HandlerIdentifier("architecture", null);
-        String arch = m_componentMetadata.getAttribute("architecture");
-        if (arch == null || arch.equalsIgnoreCase("true")) {
-            m_handlerIdentifiers.add(hi);
-        }
-        
-        // Add lifecycle callback if immediate = true
-        HandlerIdentifier hi2 = new HandlerIdentifier("callback", null);
-        String imm = m_componentMetadata.getAttribute("immediate");
-        if (! m_handlerIdentifiers.contains(hi2) && imm != null && imm.equalsIgnoreCase("true")) {
-            m_handlerIdentifiers.add(hi2);
-        }
-    }
-
-    /**
-     * Callback called by instance when disposed.
-     * @param ci : the destroyed instance
-     */
-    protected void disposed(ComponentInstance ci) {
-        String name = ci.getInstanceName();
-        m_instancesName.remove(name);
-        m_componentInstances.remove(name);
-    }
-    
-    /**
-     * Generate an instance name.
-     * @return an non already used name
-     */
-    protected synchronized String generateName() {
-        String name = m_factoryName + "-" + m_index;
-        while (m_instancesName.contains(name)) {
-            m_index = m_index + 1;
-            name = m_factoryName + "-" + m_index;
-        }
-        return name;
-    }
-    
-    /**
-     * Return the bundle context.
-     * @return the Bundle Context.
-     */
-    public 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;
-    }
-
-    /**
-     * 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);
-        props.put(Constants.SERVICE_PID, m_factoryName); // Service PID is required for the integration in the configuration admin.
-        
-        if (m_componentDesc != null) {
-            props.put("component.providedServiceSpecifications", m_componentDesc.getprovidedServiceSpecification());
-            props.put("component.properties", m_componentDesc.getProperties());
-            props.put("component.description", m_componentDesc);
-        }
-        
-        // 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)) {
-            return name.equals(hi.m_name) && hi.m_namespace == null;
-        }
-        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) {
-        try {
-            return (HandlerManager) hi.getFactory().createComponentInstance(null, sc);
-        } catch (MissingHandlerException e) {
-            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed: " + e.getMessage());
-            stop();
-            return null;
-        } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());
-            stop();
-            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());
-            stop();
-            return null;
-        }
-    }
-
-    /**
-     * Structure storing required handlers.
-     */
-    class HandlerIdentifier implements Comparable {
-        /**
-         * Factory to create this handler.
-         */
-        private HandlerFactory m_factory;
-        
-        /**
-         * Handler name.
-         */
-        private String m_name;
-        
-        /**
-         * Handler start level.
-         */
-        private int m_level = Integer.MAX_VALUE;
-        
-        /**
-         * 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 (m_namespace == null) {
-                return ((HandlerIdentifier) o).m_name.equalsIgnoreCase(m_name) && ((HandlerIdentifier) o).m_namespace == null;
-            } else {
-                return ((HandlerIdentifier) o).m_name.equalsIgnoreCase(m_name) && m_namespace.equalsIgnoreCase(((HandlerIdentifier) o).m_namespace);
-            }
-        }
-        
-        /**
-         * Get the factory object used for this handler.
-         * The object is get when used for the first time.
-         * @return the factory object.
-         */
-        public HandlerFactory getFactory() {
-            if (m_reference == null) {
-                return null;
-            }
-            if (m_factory == null) {
-                m_factory = (HandlerFactory) m_tracker.getService(getReference());
-            }
-            return m_factory;
-        }
-        
-        /**
-         * Get the handler full name (namespace:name).
-         * @return the handler full name
-         */
-        public String getFullName() {
-            if (m_namespace == null) {
-                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;
-        }
-        
-        public int getLevel() {
-            return m_level;
-        }
-        
-        /**
-         * Release the reference of the used factory.
-         */
-        public void unRef() {
-            if (m_reference != null) {
-                m_tracker.ungetService(m_reference);
-                m_factory = null;
-                m_reference = null;
-            }
-        }
-        
-        /**
-         * 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) {            
-            m_reference = ref;
-            Integer p = (Integer) m_reference.getProperty(Handler.HANDLER_LEVEL_PROPERTY);
-            if (p != null) {
-                m_level = p.intValue();
-            }
-        }
-
-        /**
-         * Start level Comparison.
-         * This method is used to sort the handler array.
-         * @param o : object on which compare.
-         * @return -1, 0, +1 according to the comparison of their start level.
-         * @see java.lang.Comparable#compareTo(java.lang.Object)
-         */
-        public int compareTo(Object o) {
-            if (o instanceof HandlerIdentifier) {
-                HandlerIdentifier hi = (HandlerIdentifier) o;
-                if (this.m_level == hi.m_level) {
-                    return 0;
-                } else if (this.m_level < hi.m_level) {
-                    return -1;
-                } else {
-                    return +1;
-                }
-            }
-            return 0;
-        }
+        return m_manipulation;
     }
 
     /**
@@ -1048,22 +336,20 @@
         /**
          * Map of defined classes [Name, Class Object].
          */
-        private Map m_definedClasses = new HashMap();
+        private final Map m_definedClasses = new HashMap();
 
         /**
          * The defineClass method.
          * @param name : name of the class
-         * @param b : the byte array of the class
+         * @param clazz : the byte array of the class
          * @param domain : the protection domain
          * @return : the defined class.
          */
-        public Class defineClass(String name, byte[] b, ProtectionDomain domain) {
-            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;
+        public Class defineClass(String name, byte[] clazz, ProtectionDomain domain) {
+            if (m_definedClasses.containsKey(name)) { return (Class) m_definedClasses.get(name); }
+            Class clas = super.defineClass(name, clazz, 0, clazz.length, domain);
+            m_definedClasses.put(name, clas);
+            return clas;
         }
 
         /**
@@ -1084,8 +370,44 @@
          * @return : the loaded class
          * @throws ClassNotFoundException : the class to load is not found
          */
-        protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+        protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
             return m_context.getBundle().loadClass(name);
         }
     }
+
+    private final class PrimitiveTypeDescription extends ComponentTypeDescription {
+
+        /**
+         * Constructor.
+         * @param factory : the represented factory.
+         */
+        public PrimitiveTypeDescription(Factory factory) {
+            super(factory);
+        }
+
+        /**
+         * Compute the properties to publish : 
+         * component.class contains the pojo class name.
+         * @return the dictionary of properties to publish
+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()
+         */
+        public Dictionary getPropertiesToPublish() {
+            Dictionary dict = super.getPropertiesToPublish();
+            if (m_classname != null) {
+                dict.put("component.class", m_classname);
+            }
+            return dict;
+        }
+
+        /**
+         * Add the "implementation-class" attribute to the type description.
+         * @return the component type description.
+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getDescription()
+         */
+        public Element getDescription() {
+            Element elem = super.getDescription();
+            elem.addAttribute(new Attribute("Implementation-Class", m_classname));
+            return elem;
+        }
+    }
 }
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
deleted file mode 100644
index a87015e..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java
+++ /dev/null
@@ -1,410 +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.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) {
-        m_factoryName = cm.getAttribute("name");
-        if (m_factoryName == null) {
-            System.err.println("A composite needs a name");
-            return false;
-        } else {
-            return true;
-        }
-    }
-    
-    /**
-     * 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)) {
-                return name.equals(hi.getName()) && hi.getNamespace() == null;
-            }
-            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 architecture != 'false'
-        String arch = m_componentMetadata.getAttribute("architecture");
-        if (arch == null || arch.equalsIgnoreCase("true")) {
-            HandlerIdentifier hi = new HandlerIdentifier("architecture", null);
-            if (! m_handlerIdentifiers.contains(hi)) { m_handlerIdentifiers.add(hi); }
-        }
-    }
-    
-    /**
-     * Stop all the instance managers.
-     */
-    public synchronized void stop() {
-        if (m_tracker != null) {
-            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;
-        } 
-        if (m_handlerIdentifiers.size() != 0) {
-            try {
-                String filter = "(&(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")"
-                    + "(" + 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());
-                stop();
-                return;
-            }
-        }
-
-        try {
-            computeFactoryState();
-        } catch (ConfigurationException e) {
-            m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
-            stop();
-            return;
-        }
-        
-        // Check if the factory should be exposed
-        if (m_isPublic) {
-            // 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);
-        }
-        
-        // Add factory state
-        props.put("factory.state", "" + m_state);
-        
-        props.put("factory.name", m_factoryName);
-        
-        return props;
-    }
-    
-    public String getClassName() {
-        return "composite";
-    }
-
-
-    /**
-     * 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 (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.
-     * @throws ConfigurationException : occurs if the component type cannot be initialized correctly.
-     */
-    protected void computeFactoryState() throws ConfigurationException {
-        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) {
-            computeDescription();
-        }
-
-        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(this);
-       
-        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());
-            stop();
-            return null;
-        } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "The creation of the composite handler " + handler.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());
-            stop();
-            return null;
-        } catch (ConfigurationException e) {
-            m_logger.log(Logger.ERROR, "The creation of the composite handler " + handler.getFullName() + " has failed (ConfigurationException): " + e.getMessage());
-            stop();
-            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
deleted file mode 100644
index bf243e9..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
+++ /dev/null
@@ -1,66 +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 Handler Abstract Class. An composite handler need implements these
- * method to be notified of lifecycle change...
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public abstract class CompositeHandler extends Handler {
-    
-    /**
-     * Composite Handler type.
-     */
-    public static final String HANDLER_TYPE = "composite";
-    
-    /**
-     * Reference on the composite manager.
-     */
-    private CompositeManager m_manager;
-    
-    /**
-     * Set the manager.
-     * This method me be called only once time.
-     * @param cm : the composite manager.
-     */
-    protected final void attach(ComponentInstance cm) {
-        m_manager = (CompositeManager) cm;
-        setLogger(m_manager.getFactory().getLogger());
-    }
-    
-    public final CompositeManager getCompositeManager() {
-        return m_manager;
-    }
-    
-    /**
-     * 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
deleted file mode 100644
index 69eb78f..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
+++ /dev/null
@@ -1,435 +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.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.felix.ipojo.architecture.Architecture;
-import org.apache.felix.ipojo.architecture.InstanceDescription;
-import org.apache.felix.ipojo.composite.CompositeServiceContext;
-import org.apache.felix.ipojo.metadata.Element;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-/**
- * iPOJO Composite manager. The composite manager class manages one instance of
- * a component type which is a composition. It manages component lifecycle, and
- * handlers...
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CompositeManager implements ComponentInstance, InstanceStateListener {
-
-    /**
-     * The context of the component.
-     */
-    private BundleContext m_context;
-
-    /**
-     * Parent factory (ComponentFactory).
-     */
-    private ComponentFactory m_factory;
-
-    /**
-     * Composite Handler list.
-     */
-    private HandlerManager[] m_handlers = new HandlerManager[0];
-
-    /**
-     * Instance State Listener List.
-     */
-    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;
-
-    /**
-     * 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, HandlerManager[] handlers) {
-        m_factory = factory;
-        m_context = bc;
-        // Initialize the service context.
-        m_internalContext = new CompositeServiceContext(m_context, this);
-        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);
-        }
-    }
-
-    /**
-     * Configure the instance manager. Stop the existing handler, clear the
-     * handler list, change the metadata, recreate the handler
-     * 
-     * @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) 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 < 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);
-
-        // Cleaning
-        m_state = DISPOSED;
-        for (int i = m_handlers.length - 1; i > -1; i--) {
-            m_handlers[i].dispose();
-        }
-        m_handlers = new HandlerManager[0];
-        m_instanceListeners.clear();
-    }
-
-    /**
-     * 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) {
-        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 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());
-        }
-
-        // Get instances description of internal instance
-        ServiceReference[] refs;
-        try {
-            refs = m_internalContext.getServiceReferences(Architecture.class.getName(), null);
-            if (refs != null) {
-                for (int i = 0; i < refs.length; i++) {
-                    Architecture arch = (Architecture) m_internalContext.getService(refs[i]);
-                    instanceDescription.addInstance(arch.getInstanceDescription());
-                    m_internalContext.ungetService(refs[i]);
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace(); // Should not happen
-        }
-        return instanceDescription;
-    }
-
-    /**
-     * 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() {
-        CompositeHandler[] h = new CompositeHandler[m_handlers.length];
-        for (int i = 0; i < m_handlers.length; i++) {
-            h[i] = (CompositeHandler) m_handlers[i].getHandler();
-        }
-        return h;
-    }
-    
-    /**
-     * Get the internal service context of this instance.
-     * @return the internal service context.
-     */
-    public ServiceContext getServiceContext() {
-        return m_internalContext;
-    }
-    
-    /**
-     * Get the actual state of the instance.
-     * @return the actual state of the instance
-     * @see org.apache.felix.ipojo.ComponentInstance#getState()
-     */
-    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;
-    }
-
-    /**
-     * Reconfigure the current instance.
-     * @param configuration : the new instance configuration.
-     * @see org.apache.felix.ipojo.ComponentInstance#reconfigure(java.util.Dictionary)
-     */
-    public void reconfigure(Dictionary configuration) {
-        for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].reconfigure(configuration);
-        }
-    }
-
-    /**
-     * 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) {
-        synchronized (m_instanceListeners) {
-            m_instanceListeners.remove(listener);
-        }
-    }
-
-    /**
-     * Set the state of the component. 
-     * if the state changed call the stateChanged(int) method on the handlers.
-     * @param state : new state
-     */
-    public void setState(int state) {
-        if (m_state != state) {
-            if (state > m_state) {
-                // The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower
-                m_state = state;
-                for (int i = 0; i < m_handlers.length; i++) {
-                    m_handlers[i].getHandler().stateChanged(state);
-                }
-            } else {
-                // The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)
-                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);
-        }
-    }
-    
-    /**
-     * Kill the current instance.
-     * Only the factory of this instance can call this method.
-     */
-    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 = m_handlers.length - 1; i > -1; 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
index 90c9ba4..cde3140 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
@@ -29,11 +29,6 @@
      * Serialization Id.
      */
     private static final long serialVersionUID = 1L;
-
-    /**
-     * Message.
-     */
-    private String m_message;
     
     /**
      * Component Type on which the error occurs.
@@ -46,8 +41,8 @@
      * @param typ : component type
      */
     ConfigurationException(String mes, String typ) {
+        super(mes);
         m_type = typ;
-        m_message = mes;
     }
     
     /**
@@ -55,7 +50,7 @@
      * @param mes : message
      */
     public ConfigurationException(String mes) {
-        m_message = mes;
+        super(mes);
     }
     
     /**
@@ -64,10 +59,10 @@
      * @see java.lang.Throwable#getMessage()
      */
     public String getMessage() {
-        if (m_type != null) {
-            return "The configuration is not correct for the type " + m_type + " : " + m_message;
+        if (m_type == null) {
+            return super.getMessage();
         } else {
-            return m_message;
+            return "The configuration is not correct for the type " + m_type + " : " + super.getMessage();
         }
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextListener.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextListener.java
new file mode 100644
index 0000000..d592c5c
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextListener.java
@@ -0,0 +1,36 @@
+/* 
+ * 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;
+
+
+/**
+ * Context Source Listener.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ContextListener {
+    
+    /**
+     * A monitored value has been modified.
+     * @param source : context source containing the property
+     * @param property : modified property name
+     * @param value : new value of the property
+     */
+    void update(ContextSource source, String property, Object value);
+
+}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextSource.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextSource.java
new file mode 100644
index 0000000..e55f163
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextSource.java
@@ -0,0 +1,57 @@
+/* 
+ * 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;
+
+
+/**
+ * Context Source service interface.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ContextSource {
+    
+    /**
+     * Get the current value of the given property.
+     * @param property : property name
+     * @return the property value, null if unknown
+     */
+    Object getProperty(String property);
+    
+    /**
+     * Get the whole context.
+     * @return the dictionary [Property, Value]
+     */
+    Dictionary getContext();
+    
+    /**
+     * Register a context listener on the given set of properties.
+     * The listener will be notified of every change made on these properties.
+     * @param listener : the context listener to register.
+     * @param properties : property set monitored by the listener.
+     */
+    void registerContextListener(ContextListener listener, String[] properties);
+    
+    /**
+     * Unregister the given context listener.
+     * @param listener : the listener to unregister.
+     */
+    void unregisterContextListener(ContextListener listener);
+
+}
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 aeb4c0f..fd9ab38 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
@@ -19,20 +19,27 @@
 package org.apache.felix.ipojo;
 
 import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.ManifestMetadataParser;
 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.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.SynchronousBundleListener;
-import org.osgi.service.log.LogService;
 
 /**
  * iPOJO Extender.
@@ -42,39 +49,52 @@
 public class Extender implements SynchronousBundleListener, BundleActivator {
 
     /**
-     * iPOJO Manifest header.
+     * iPOJO Component Type and Instance declaration header.
      */
     private static final String IPOJO_HEADER = "iPOJO-Components";
-    
+
+    /**
+     * iPOJO Extension declaration header. 
+     */
+    private static final String IPOJO_EXTENSION = "IPOJO-Extension";
+
+    /**
+     * iPOJO Extender logger.
+     */
+    private Logger m_logger;
+
     /**
      * iPOJO Bundle Context.
      */
     private BundleContext m_context;
-    
+
     /**
-     * Dictionary of [BundleId, Factory List]. 
+     * Declared instance manager.
      */
-    private Dictionary m_components;
-    
+    private InstanceCreator m_creator;
+
     /**
-     * Dictionary of [BundleId, Instance Creator]. 
+     * iPOJO Bundle.
      */
-    private Dictionary m_creators;
-    
+    private Bundle m_bundle;
+
     /**
-     * iPOJO Bundle Id.
+     * List of factory types.
      */
-    private long m_bundleId;
-    
+    private List m_factoryTypes = new ArrayList();
+
+    /**
+     * List of unbound types.
+     */
+    private final List m_unboundTypes = new ArrayList();
+
     /**
      * Bundle Listener Notification.
      * @param event : the bundle event.
      * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
      */
     public synchronized void bundleChanged(BundleEvent event) {
-        if (event.getBundle().getBundleId() == m_bundleId) {
-            return;
-        }
+        if (event.getBundle() == m_bundle) { return; }
 
         switch (event.getType()) {
             case BundleEvent.STARTED:
@@ -83,7 +103,7 @@
             case BundleEvent.STOPPING:
                 closeManagementFor(event.getBundle());
                 break;
-            default: 
+            default:
                 break;
         }
 
@@ -94,42 +114,109 @@
      * @param bundle : the bundle.
      */
     private void closeManagementFor(Bundle bundle) {
-        ComponentFactory[] cfs = (ComponentFactory[]) m_components.get(bundle);
-        InstanceCreator creator = (InstanceCreator) m_creators.get(bundle);
-        if (cfs == null && creator == null) { return; }
-        for (int i = 0; cfs != null && i < cfs.length; i++) {
-            ComponentFactory factory = cfs[i];
-            factory.stop();
+        List toRemove = new ArrayList();
+        for (int k = 0; k < m_factoryTypes.size(); k++) {
+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) m_factoryTypes.get(k);
+
+            // Delete instances declared in the leaving bundle.
+            m_creator.removeInstancesFromBundle(bundle.getBundleId());
+
+            // Look for component type created from this bundle.
+            if (mft.m_created != null) {
+                List cfs = (List) mft.m_created.remove(bundle);
+                for (int i = 0; cfs != null && i < cfs.size(); i++) {
+                    IPojoFactory factory = (IPojoFactory) cfs.get(i);
+                    m_creator.removeFactory(factory);
+                    factory.stop();
+                }
+            }
+
+            // If the leaving bundle has declared mft : destroy all created factories.
+            if (mft.m_bundle == bundle) {
+                if (mft.m_created != null) {
+                    Iterator iterator = mft.m_created.keySet().iterator();
+                    while (iterator.hasNext()) {
+                        Bundle key = (Bundle) iterator.next();
+                        List list = (List) mft.m_created.get(key);
+                        for (int i = 0; i < list.size(); i++) {
+                            IPojoFactory factory = (IPojoFactory) list.get(i);
+                            factory.stop();
+                            m_unboundTypes.add(new UnboundComponentType(mft.m_type, factory.m_componentMetadata, factory.getBundleContext()
+                                    .getBundle()));
+                        }
+                    }
+                }
+                toRemove.add(mft);
+            }
         }
-        if (creator != null) { creator.stop(); }
-        
-        m_components.remove(bundle);
-        m_creators.remove(bundle);
-        
+
+        for (int i = 0; i < toRemove.size(); i++) {
+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) toRemove.get(i);
+            m_logger.log(Logger.WARNING, "The factory type available: " + mft.m_type + " is no more available");
+            mft.m_bundle = null;
+            mft.m_clazz = null;
+            mft.m_created = null;
+            mft.m_type = null;
+            m_factoryTypes.remove(mft);
+        }
     }
 
     /**
-     * Check if the given bundle is an iPOJO bundle, and begin the iPOJO management is true. 
+     * Check if the given bundle is an iPOJO bundle, and begin the iPOJO management is true.
      * @param bundle : the bundle to check.
      */
     private void startManagementFor(Bundle bundle) {
-        // Check bundle
         Dictionary dict = bundle.getHeaders();
+        // Check for abstract factory type
+        String typeHeader = (String) dict.get(IPOJO_EXTENSION);
+        if (typeHeader != null) {
+            parseAbstractFactoryType(bundle, typeHeader);
+        }
+
+        // Check bundle
         String header = (String) dict.get(IPOJO_HEADER);
-        if (header == null) {
-            return;
-        } else {
+        if (header != null) {
             try {
                 parse(bundle, header);
             } catch (IOException e) {
-                err("An exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);
+                m_logger.log(Logger.ERROR, "An exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);
             } catch (ParseException e) {
-                err("A parse exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);
+                m_logger.log(Logger.ERROR, "A parse exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);
             }
         }
-        
     }
-    
+
+    /**
+     * Parse an IPOJO-Extension manifest header.
+     * @param bundle : bundle containing the header.
+     * @param header : header to parse.
+     */
+    private void parseAbstractFactoryType(Bundle bundle, String header) {
+        String[] arr = ParseUtils.split(header, ",");
+        for (int i = 0; arr != null && i < arr.length; i++) {
+            String[] arr2 = ParseUtils.split(arr[i], ":");
+            String type = arr2[0];
+            Class clazz;
+            try {
+                clazz = bundle.loadClass(arr2[1]);
+            } catch (ClassNotFoundException e) {
+                m_logger.log(Logger.ERROR, "Cannot load the extension " + type, e);
+                return;
+            }
+            ManagedAbstractFactoryType mft = new ManagedAbstractFactoryType(clazz, type, bundle);
+            m_factoryTypes.add(mft);
+            m_logger.log(Logger.WARNING, "New factory type available: " + type);
+
+            for (int j = m_unboundTypes.size() - 1; j >= 0; j--) {
+                UnboundComponentType unbound = (UnboundComponentType) m_unboundTypes.get(j);
+                if (unbound.m_type.equals(type)) {
+                    createAbstractFactory(unbound.m_bundle, unbound.m_description);
+                    m_unboundTypes.remove(unbound);
+                }
+            }
+        }
+    }
+
     /**
      * Parse the internal metadata (from the manifest (in the iPOJO-Components property)).
      * @param bundle : the owner bundle.
@@ -140,35 +227,40 @@
     private void parse(Bundle bundle, String components) throws IOException, ParseException {
         ManifestMetadataParser parser = new ManifestMetadataParser();
         parser.parseHeader(components);
-          
-        Element[] componentsMetadata = parser.getComponentsMetadata(); // Get the component type declaration
-        for (int i = 0; i < componentsMetadata.length; i++) { addComponentFactory(bundle, componentsMetadata[i]); }
-        
-        start(bundle, parser.getInstances());
+
+        Element[] metadata = parser.getComponentsMetadata(); // Get the component type declaration
+        for (int i = 0; i < metadata.length; i++) {
+            createAbstractFactory(bundle, metadata[i]);
+        }
+
+        Dictionary[] instances = parser.getInstances();
+        for (int i = 0; instances != null && i < instances.length; i++) {
+            m_creator.addInstance(instances[i], bundle.getBundleId());
+        }
     }
 
     /**
      * iPOJO Starting method.
-     * @param bc : iPOJO bundle context.
-     * @throws Exception : the start method failed.
+     * @param context : iPOJO bundle context.
      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
      */
-    public void start(BundleContext bc) throws Exception {
-        m_context = bc;
-        m_bundleId = bc.getBundle().getBundleId();
-        m_components = new Hashtable();
-        m_creators = new Hashtable();
+    public void start(BundleContext context) {
+        m_context = context;
+        m_bundle = context.getBundle();
+        m_creator = new InstanceCreator(context);
+
+        m_logger = new Logger(m_context, "IPOJO Extender");
 
         // Begin by initializing core handlers
-        startManagementFor(bc.getBundle());
+        startManagementFor(m_bundle);
 
         synchronized (this) {
             // listen to any changes in bundles.
             m_context.addBundleListener(this);
             // compute already started bundles.
-            for (int i = 0; i < bc.getBundles().length; i++) {
-                if (bc.getBundles()[i].getState() == Bundle.ACTIVE) {
-                    startManagementFor(bc.getBundles()[i]);
+            for (int i = 0; i < context.getBundles().length; i++) {
+                if (context.getBundles()[i].getState() == Bundle.ACTIVE) {
+                    startManagementFor(context.getBundles()[i]);
                 }
             }
         }
@@ -176,96 +268,238 @@
 
     /**
      * Stop the iPOJO Management.
-     * @param bc : bundle context.
-     * @throws Exception : the stop method failed.
+     * @param context : bundle context.
      * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
      */
-    public void stop(BundleContext bc) throws Exception {
+    public void stop(BundleContext context) {
         m_context.removeBundleListener(this);
-        Enumeration e = m_components.keys();
-        while (e.hasMoreElements()) {
-            ComponentFactory[] cfs = (ComponentFactory[]) m_components.get(e.nextElement());
-            for (int i = 0; i < cfs.length; i++) {
-                cfs[i].stop();
+
+        for (int k = 0; k < m_factoryTypes.size(); k++) {
+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) m_factoryTypes.get(k);
+
+            if (mft.m_created != null) {
+                Iterator iterator = mft.m_created.keySet().iterator();
+                while (iterator.hasNext()) {
+                    Bundle key = (Bundle) iterator.next();
+                    List list = (List) mft.m_created.get(key);
+                    for (int i = 0; i < list.size(); i++) {
+                        IPojoFactory factory = (IPojoFactory) list.get(i);
+                        m_creator.removeFactory(factory);
+                        factory.dispose();
+                    }
+                }
             }
         }
-        m_components = null;
-        Enumeration e2 = m_creators.keys();
-        while (e2.hasMoreElements()) {
-            InstanceCreator creator = (InstanceCreator) m_creators.remove(e2.nextElement());
-            creator.stop();
-        }
-        m_creators = null;
+
+        m_factoryTypes = null;
+        m_creator = null;
     }
-    
+
     /**
      * Add a component factory to the factory list.
-     * @param cm : the new component metadata.
+     * @param metadata : the new component metadata.
      * @param bundle : the bundle.
      */
-    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
-        if (cfs != null && cfs.length != 0) {
-            ComponentFactory[] newFactory = new ComponentFactory[cfs.length + 1];
-            System.arraycopy(cfs, 0, newFactory, 0, cfs.length);
-            newFactory[cfs.length] = factory;
-            cfs = newFactory;
-            m_components.put(bundle, cfs);
-        } else {
-            m_components.put(bundle, new ComponentFactory[] {factory}); // Else create an array of size one with the new Factory 
-        }
-    }
-    
-    /**
-     * Start the management of factories and create instances.
-     * @param bundle : the bundle. 
-     * @param confs : the instances to create.
-     */
-    private void start(Bundle bundle, Dictionary[] confs) {
-        ComponentFactory[] cfs = (ComponentFactory[]) m_components.get(bundle);
-        
-        // Start the factories
-        if (cfs != null) {
-            for (int j = 0; j < cfs.length; j++) {
-                cfs[j].start();
+    private void createAbstractFactory(Bundle bundle, Element metadata) {
+        ManagedAbstractFactoryType factoryType = null;
+        // First, look for factory-type (component, handler, composite ...)
+        for (int i = 0; i < m_factoryTypes.size(); i++) {
+            ManagedAbstractFactoryType type = (ManagedAbstractFactoryType) m_factoryTypes.get(i);
+            if (type.m_type.equals(metadata.getName())) {
+                factoryType = type;
+                break;
             }
         }
 
-        // Create the instance creator if needed.
-        if (confs.length > 0) {
-            m_creators.put(bundle, new InstanceCreator(bundle.getBundleContext(), confs, cfs));
+        // If not found, return. It will wait for a new component type factory.
+        if (factoryType == null) {
+            m_logger.log(Logger.WARNING, "Type of component not yet recognized : " + metadata.getName());
+            m_unboundTypes.add(new UnboundComponentType(metadata.getName(), metadata, bundle));
+            return;
+        }
+
+        // Once found, we invoke the AbstractFactory constructor to create the component factory. 
+        Class clazz = factoryType.m_clazz;
+        try {
+            // Look for the constructor, and invoke it.
+            Constructor cst = clazz.getConstructor(new Class[] { BundleContext.class, Element.class });
+            IPojoFactory factory = (IPojoFactory) cst.newInstance(new Object[] { getBundleContext(bundle), metadata });
+
+            // Add the created factory in the m_createdFactories map.
+            if (factoryType.m_created == null) {
+                factoryType.m_created = new HashMap();
+                List list = new ArrayList();
+                list.add(factory);
+                factoryType.m_created.put(bundle, list);
+            } else {
+                List list = (List) factoryType.m_created.get(bundle);
+                if (list == null) {
+                    list = new ArrayList();
+                    list.add(factory);
+                    factoryType.m_created.put(bundle, list);
+                } else {
+                    list.add(factory);
+                }
+            }
+
+            // Start the created factory.
+            factory.start();
+            // Then add the factory to the instance creator.
+            m_creator.addFactory(factory);
+
+        } catch (SecurityException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);
+        } catch (NoSuchMethodException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName() + ": the given class constructor cannot be found");
+        } catch (IllegalArgumentException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);
+        } catch (InstantiationException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);
+        } catch (IllegalAccessException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);
+        } catch (InvocationTargetException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e.getTargetException());
         }
     }
-    
+
     /**
-     * Log an error message in a log service (if available) and display the message in the console.
-     * @param message : the message to log
-     * @param t : an attached error (can be null)
+     * Structure storing an iPOJO extension.
      */
-    private void err(String message, Throwable t) {
-        ServiceReference ref = m_context.getServiceReference(LogService.class.getName());
-        if (ref != null) {
-            LogService log = (LogService) m_context.getService(ref);
-            log.log(LogService.LOG_ERROR, message, t);
-            m_context.ungetService(ref);
-        }
-        if (t != null) {
-            System.err.println("[iPOJO-Core] " + message + " : " + t.getMessage());
-        } else {
-            System.err.println("[iPOJO-Core] " + message);
+    private final class ManagedAbstractFactoryType {
+        /**
+         * TYpe (i.e.) name of the extension.
+         */
+        String m_type;
+
+        /**
+         * Abstract Factory class.
+         */
+        Class m_clazz;
+
+        /**
+         * Bundle object containing the declaration of the extension.
+         */
+        Bundle m_bundle;
+
+        /**
+         * Factories created by this extension. 
+         */
+        private Map m_created;
+
+        /**
+         * Constructor.
+         * @param factory : abstract factory class.
+         * @param type : name of the extension.
+         * @param bundle : bundle declaring the extension.
+         */
+        protected ManagedAbstractFactoryType(Class factory, String type, Bundle bundle) {
+            m_bundle = bundle;
+            m_clazz = factory;
+            m_type = type;
         }
     }
+
+    /**
+     * Structure storing unbound component type declaration.
+     * Unbound means that there is no extension able to manage it.
+     */
+    private final class UnboundComponentType {
+        /**
+         * Component type description.
+         */
+        private final Element m_description;
+
+        /**
+         * Bundle declaring this type.
+         */
+        private final Bundle m_bundle;
+
+        /**
+         * Required extension name.
+         */
+        private final String m_type;
+
+        /**
+         * Constructor.
+         * @param description : description of the component type.
+         * @param bundle : bundle declaring this type.
+         * @param type : required extension name.
+         */
+        protected UnboundComponentType(String type, Element description, Bundle bundle) {
+            m_type = type;
+            m_description = description;
+            m_bundle = bundle;
+        }
+    }
+
+    /**
+     * Compute the bundle context from the bundle class by introspection.
+     * @param bundle : bundle.
+     * @return the bundle context object or null if not found.
+     */
+    public BundleContext getBundleContext(Bundle bundle) {
+        if (bundle == null) { return null; }
+
+        // getBundleContext (OSGi 4.1)
+        Method meth = null;
+        try {
+            meth = bundle.getClass().getMethod("getBundleContext", new Class[0]);
+        } catch (SecurityException e) {
+            // Nothing do to, will try the Equinox method
+        } catch (NoSuchMethodException e) {
+            // Nothing do to, will try the Equinox method
+        }
+
+        // try Equinox getContext if not found.
+        if (meth == null) {
+            try {
+                meth = bundle.getClass().getMethod("getContext", new Class[0]);
+            } catch (SecurityException e) {
+                // Nothing do to, will try field inspection
+            } catch (NoSuchMethodException e) {
+                // Nothing do to, will try field inspection
+            }
+        }
+
+        if (meth != null) {
+            if (! meth.isAccessible()) { 
+                // If not accessible, try to set the accessibility.
+                meth.setAccessible(true);
+            }
+            try {
+                return (BundleContext) meth.invoke(bundle, new Object[0]);
+            } catch (IllegalArgumentException e) {
+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);
+                return null;
+            } catch (IllegalAccessException e) {
+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);
+                return null;
+            } catch (InvocationTargetException e) {
+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e.getTargetException());
+                return null;
+            }
+        }
+
+        // Else : Field inspection (KF and Prosyst)        
+        Field[] fields = bundle.getClass().getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            if (BundleContext.class.isAssignableFrom(fields[i].getType())) {
+                if (!fields[i].isAccessible()) {
+                    fields[i].setAccessible(true);
+                }
+                try {
+                    return (BundleContext) fields[i].get(bundle);
+                } catch (IllegalArgumentException e) {
+                    m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);
+                    return null;
+                } catch (IllegalAccessException e) {
+                    m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);
+                    return null;
+                }
+            }
+        }
+        m_logger.log(Logger.ERROR, "Cannot find the BundleContext for " + bundle.getSymbolicName(), null);
+        return null;
+    }
+
 }
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 bcc2d55..a8bff35 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
@@ -21,7 +21,7 @@
 import java.util.Dictionary;
 import java.util.List;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.osgi.framework.BundleContext;
 
@@ -72,7 +72,7 @@
      * Get the component type description.
      * @return the component type description object
      */
-    ComponentDescription getComponentDescription();
+    ComponentTypeDescription getComponentDescription();
 
     /**
      * Check if the given configuration is acceptable as a configuration of a component instance.
@@ -97,15 +97,15 @@
 
     /**
      * Add a factory state listener on the current factory.
-     * @param l : the listener to add
+     * @param listener : the listener to add
      */
-    void addFactoryStateListener(FactoryStateListener l);
+    void addFactoryStateListener(FactoryStateListener listener);
 
     /**
      * Remove the given factory state listener from the listener list.
-     * @param l : the listener to remove
+     * @param listener : the listener to remove
      */
-    void removeFactoryStateListener(FactoryStateListener l);
+    void removeFactoryStateListener(FactoryStateListener listener);
 
     /**
      * Get the list of missing handlers.
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.java
new file mode 100644
index 0000000..d8d4823
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.java
@@ -0,0 +1,47 @@
+/* 
+ * 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;
+
+/**
+* Field interceptor.
+* A class implementing this interface is able to be notified of field accesses.
+* The listener need to be register on the instance manager. 
+* 
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public interface FieldInterceptor {
+    
+    /**
+     * This method is called when a PUTFIELD operation is detected.
+     * @param pojo : the pojo object setting the value
+     * @param fieldName : the field name
+     * @param value : the value passed to the field
+     */
+    void onSet(Object pojo, String fieldName, Object value);
+
+    /**
+     * This method is called when a GETFIELD operation is detected.
+     * @param pojo : the pojo object getting the value
+     * @param fieldName : the field name
+     * @param value : the value passed to the field (by the previous call)
+     * @return : the managed value of the field
+     */
+    Object onGet(Object pojo, String fieldName, Object value);
+
+}
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 48cb786..42107af 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,7 +20,7 @@
 
 import java.util.Dictionary;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.util.Logger;
@@ -31,17 +31,17 @@
  * @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. 
      */
@@ -51,39 +51,73 @@
      * Handler priority.
      */
     public static final String HANDLER_LEVEL_PROPERTY = "handler.level";
-    
+
     /**
-     * Handler logger.
+     * Handler validity.
      */
-    private Logger m_logger;
-    
+    protected boolean m_isValid = true;
+
     /**
-     * Set the logger use by this handler.
-     * @param logger : the logger object to use.
+     * HandlerManager managing the current handler.
      */
-    final void setLogger(Logger logger) {
-        m_logger = logger;
-    }
-    
+    protected HandlerManager m_instance;
+
     /**
-     * Log method.
-     * @param level : message level (Logger class constant)
+     * Set the factory attached to this handler object.
+     * This method must be override to depend on each component factory type. 
+     * @param factory : the factory.
+     */
+    public abstract void setFactory(Factory factory);
+
+    /**
+     * Get the logger to use in the handler.
+     * This method must be override to depend on each component factory type logging policy.
+     * @return the logger.
+     */
+    public abstract Logger getLogger();
+
+    /**
+     * Log method (warning).
      * @param message : message to log
      */
-    public final void log(int level, String message) {
-        m_logger.log(level, message);
+    public final void warn(String message) {
+        getLogger().log(Logger.WARNING, message);
     }
-    
+
     /**
-     * Log method.
-     * @param level : message level (Logger class constant)
+     * Log method (error).
      * @param message : message to log
-     * @param ex : exception to attach to the message
      */
-    public final void log(int level, String message, Throwable ex) {
-        m_logger.log(level, message, ex);
+    public final void error(String message) {
+        getLogger().log(Logger.ERROR, message);
     }
-    
+
+    /**
+     * Log method (info).
+     * @param message : message to log
+     */
+    public final void info(String message) {
+        getLogger().log(Logger.INFO, message);
+    }
+
+    /**
+     * Log method (warning).
+     * @param message : message to log
+     * @param exception : exception to attach to the message
+     */
+    public final void warn(String message, Throwable exception) {
+        getLogger().log(Logger.WARNING, message, exception);
+    }
+
+    /**
+     * Log method (error).
+     * @param message : message to log
+     * @param exception : exception to attach to the message
+     */
+    public final void error(String message, Throwable exception) {
+        getLogger().log(Logger.ERROR, message, exception);
+    }
+
     /**
      * Get a plugged handler of the same container.
      * This method must be call only in the start method (or after). 
@@ -93,41 +127,65 @@
      * @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.
+     * @param instance : the component instance on which the current handler will be attached.
      */
-    protected abstract void attach(ComponentInstance ci);
-    
+    protected abstract void attach(ComponentInstance instance);
+
     /**
      * Check if the current handler is valid.
+     * This check test the handlers validity.
      * This method must not be override.
      * @return true if the handler is valid.
      */
     public final boolean isValid() {
         return ((Pojo) this).getComponentInstance().getState() == ComponentInstance.VALID;
     }
-    
-    
+
+    /**
+     * Set the validity of the current handler.
+     * @param isValid : if true the handler becomes valid, else it becomes invalid.
+     */
+    public final void setValidity(boolean isValid) {
+        if (m_isValid != isValid) {
+            m_isValid = isValid;
+            HandlerManager instance = getHandlerManager();
+            if (isValid) {
+                instance.stateChanged(instance, ComponentInstance.VALID);
+            } else {
+                instance.stateChanged(instance, ComponentInstance.INVALID);
+            }
+        }
+    }
+
+    public final boolean getValidity() {
+        return m_isValid;
+    }
+
     /**
      * Get the component instance of the current handler.
      * @return : the component instance.
      */
-    public final ComponentInstance getInstance() {
-        return ((Pojo) this).getComponentInstance();
+    public final HandlerManager getHandlerManager() {
+        if (m_instance != null) { return m_instance; }
+        m_instance = (HandlerManager) ((Pojo) this).getComponentInstance();
+        return m_instance;
     }
-    
+
     /**
      * 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 typeDesc : 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 {  }
+    public void initializeComponentFactory(ComponentTypeDescription typeDesc, Element metadata) throws ConfigurationException {
+        // The default implementation does nothing.
+    }
 
     /**
      * Configure the handler.
@@ -151,7 +209,9 @@
      * This method is called when the component state changed.
      * @param state : the new state
      */
-    public void stateChanged(int state) { }
+    public void stateChanged(int state) {
+        // The default implementation does nothing.
+    }
 
     /**
      * Return the current handler description.
@@ -166,5 +226,7 @@
      * The instance is reconfiguring.
      * @param configuration : New instance configuration.
      */
-    public void reconfigure(Dictionary configuration) { }
+    public void reconfigure(Dictionary configuration) {
+        // The default implementation does nothing.
+    }
 }
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
index 04bc706..08bff14 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
@@ -18,20 +18,12 @@
  */
 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.architecture.ComponentTypeDescription;
 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.InvalidSyntaxException;
-import org.osgi.framework.ServiceRegistration;
 
 /**
  * The component factory manages component instance objects. This management
@@ -43,20 +35,20 @@
 public class HandlerFactory extends ComponentFactory implements Factory {
 
     /**
-     * Service Registration of this factory (Factory & ManagedServiceFactory).
+     * iPOJO Default Namespace.
      */
-    private ServiceRegistration m_sr;
-    
+    public static final String IPOJO_NAMESPACE = "org.apache.felix.ipojo";
+
     /**
      * Handler type (composite|primitive).
      * Default: handler.
      */
     private String m_type = "primitive";
-    
+
     /**
      * Default iPOJO Namespace.
      */
-    private String m_namespace = IPojoConfiguration.IPOJO_NAMESPACE;
+    private String m_namespace = IPOJO_NAMESPACE;
 
     /**
      * Get the handler start level.
@@ -67,114 +59,67 @@
 
     /**
      * Create a composite factory.
-     * @param bc : bundle context
-     * @param cm : metadata of the component to create
+     * @param context : bundle context
+     * @param metadata : metadata of the component to create
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
      */
-    public HandlerFactory(BundleContext bc, Element cm) {
-        super(bc, cm);
-        
+    public HandlerFactory(BundleContext context, Element metadata) throws ConfigurationException {
+        super(context, metadata);
+
         // Get the name
-        m_factoryName = cm.getAttribute("name").toLowerCase();
-        if (m_factoryName == null) {
-            System.err.println("An Handler needs a name");
-            return;
-        }
-        
+        m_factoryName = metadata.getAttribute("name");
+        if (m_factoryName == null) { throw new ConfigurationException("An Handler needs a name"); }
+
         // Get the type
-        String t = cm.getAttribute("type");
-        if (t != null) {
-            m_type = t;
+        String type = metadata.getAttribute("type");
+        if (type != null) {
+            m_type = type;
         }
-        
-        String l = cm.getAttribute("level");
-        if (l != null) {
-            m_level = new Integer(l).intValue();
+
+        String level = metadata.getAttribute("level");
+        if (level != null) {
+            m_level = new Integer(level).intValue();
         }
-        
+
         // Get the namespace
-        String ns = cm.getAttribute("namespace");
-        if (ns != null) {
-            m_namespace = ns.toLowerCase();
-        }        
+        String namespace = metadata.getAttribute("namespace");
+        if (namespace != null) {
+            m_namespace = namespace.toLowerCase();
+        }
     }
-    
+
     public String getNamespace() {
         return m_namespace;
     }
-    
+
     public String getHandlerName() {
         return m_namespace + ":" + getName();
     }
-    
+
     public String getType() {
         return m_type;
     }
-    
+
     public int getStartLevel() {
         return m_level;
     }
 
-    /**
-     * Start all the instance managers.
-     */
-    public synchronized void start() {
-        if (m_sr != null) { // Already started.
-            return;
-        }
-        
-        if (m_handlerIdentifiers.size() != 0) {
-            try {
-                String filter = "(&(" + 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());
-                stop();
-                return;
-            }
-        }
-                
-        try {
-            computeFactoryState();
-        } catch (ConfigurationException e) {
-            m_logger.log(Logger.ERROR, "Cannot initilize the factory " + e.getMessage());
-            stop();
-            return;
-        }
-        
-        // Exposition of the factory service (always public for handlers)
-        m_sr = m_context.registerService(new String[] { Factory.class.getName()}, this, getProperties());
+    public ComponentTypeDescription getComponentTypeDescription() {
+        return new HandlerTypeDescription(this);
     }
-    
+
     /**
      * 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;
-        }
-        
+    public synchronized void stopping() {
         if (m_tracker != null) {
             m_tracker.close();
             m_tracker = null;
         }
-        
-        // Release each handler
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            ((HandlerIdentifier) m_handlerIdentifiers.get(i)).unRef();
-        }
-        
-        m_handlerIdentifiers.clear();        
-        m_listeners.clear();
-        m_state = INVALID;        
     }
-    
-    
+
     /**
      * Compute factory service properties.
      * This method add three mandatory handler factory properties (name, namespace and type)
@@ -183,164 +128,53 @@
      */
     protected Properties getProperties() {
         Properties props = new Properties();
-        
-        // Add factory state
-        props.put("factory.state", "" + m_state);
 
-        props.put(Handler.HANDLER_NAME_PROPERTY, m_factoryName);
-        props.put(Handler.HANDLER_NAMESPACE_PROPERTY, m_namespace);
-        props.put(Handler.HANDLER_TYPE_PROPERTY, m_type);
-        if (m_level != Integer.MAX_VALUE) {
-            props.put(Handler.HANDLER_LEVEL_PROPERTY, new Integer(m_level));
-        }
-        
         return props;
     }
-    
-    /**
-     * Compute handler factory state.
-     * @throws ConfigurationException : occurs when an handler cannot be initialized.
-     */
-    protected void computeFactoryState() throws ConfigurationException {
-        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) {            
-            if (m_state == INVALID) {
-                m_state = VALID;
-                
-                if (m_sr == null) {
-                    m_componentDesc = new ComponentDescription(this);
-                    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.setLogger(getLogger());
-                        ch.initializeComponentFactory(m_componentDesc, m_componentMetadata);
-                        ((Pojo) ch).getComponentInstance().dispose();
-                    }
-                }
-                
-                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;
-            }
-        } else {
-            if (m_state == VALID) {
-                m_state = INVALID;
-                
-                // Notify listeners.
-                for (int i = 0; i < m_listeners.size(); i++) {
-                    ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
-                }
 
-                // Dispose created instances.
-                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.m_name);
-                }
-
-                m_componentInstances.clear();
-
-                if (m_sr != null) {
-                    m_sr.setProperties(getProperties());
-                }
-                
-                return;
-            }
-        }
-    }
-    
     /**
      * 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.
+     * @param context : the service context to push for this instance.
+     * @param handlers : handler array to used.
      * @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 synchronized ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {
-        if (m_state == Factory.INVALID) {
-            throw new MissingHandlerException(getMissingHandlers());
-        }
-        
-        if (configuration == null) {
-            configuration = new Properties();
-        }
-        
-        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[handlers.size()]));
+    public ComponentInstance createInstance(Dictionary configuration, IPojoContext context, HandlerManager[] handlers) throws ConfigurationException {
+        HandlerManager instance = new HandlerManager(this, context, handlers);
         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) {
-        try {
-            return (HandlerManager) hi.getFactory().createComponentInstance(null, sc);
-        } catch (MissingHandlerException e) {
-            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed: " + e.getMessage());
-            stop();
-            return null;
-        } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());
-            stop();
-            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());
-            stop();
-            return null;
+
+    private class HandlerTypeDescription extends ComponentTypeDescription {
+
+        /**
+         * Constructor.
+         * @param factory : factory.
+         */
+        public HandlerTypeDescription(Factory factory) {
+            super(factory);
+        }
+
+        /**
+         * Add properties to publish : 
+         * handler.name, handler.namespace, handler.type and handler.level if the level is not Integer.MAX.
+         * @return return the dictionary to publish.
+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()
+         */
+        public Dictionary getPropertiesToPublish() {
+            Dictionary props = super.getPropertiesToPublish();
+
+            props.put(Handler.HANDLER_NAME_PROPERTY, m_factoryName);
+            props.put(Handler.HANDLER_NAMESPACE_PROPERTY, m_namespace);
+            props.put(Handler.HANDLER_TYPE_PROPERTY, m_type);
+            if (m_level != Integer.MAX_VALUE) {
+                props.put(Handler.HANDLER_LEVEL_PROPERTY, new Integer(m_level));
+            }
+            return props;
         }
     }
 }
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
index 7754ef5..e2f4003 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
@@ -24,12 +24,12 @@
 import org.osgi.framework.BundleContext;
 
 /**
-* The handler manager manages an handler instance.
-* 
-* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
-*/
+ * 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).
      */
@@ -38,13 +38,13 @@
     /**
      * Constructor.
      * @param factory : handler factory
-     * @param bc : bundle context
+     * @param context : bundle context
      * @param handlers : handler array
      */
-    public HandlerManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
-        super(factory, bc, handlers);
+    public HandlerManager(ComponentFactory factory, BundleContext context, HandlerManager[] handlers) {
+        super(factory, context, handlers);
     }
-    
+
     /**
      * Get the contained handler object.
      * If not already created it creates the object.
@@ -56,73 +56,68 @@
         }
         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 instance : component instance on which the handler will be attached.
+     * @param metadata : component metadata.
      * @param configuration : instance configuration.
      * @throws ConfigurationException if the handler configuration failed.
      */
-    public void init(ComponentInstance ci, Element cm, Dictionary configuration) throws ConfigurationException {
+    public void init(ComponentInstance instance, Element metadata, Dictionary configuration) throws ConfigurationException {
         createHandlerObject();
-        m_handler.attach(ci);
-        m_handler.configure(cm, configuration);
+        m_handler.setFactory(instance.getFactory());
+        m_handler.attach(instance);
+        m_handler.configure(metadata, 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;
-        }
+        m_handler = (Handler) createPojoObject();
     }
-    
+
     /**
      * Start the instance manager.
      */
     public synchronized void start() {
-        if (m_state != STOPPED) {
-            return;
-        } // Instance already started
+        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()) {
+            if (!m_handlers[i].getHandler().isValid()) {
                 setState(INVALID);
                 return;
             }
         }
-        setState(VALID);
+        if (m_handler.getValidity()) {
+            setState(VALID);
+        } else {
+            setState(INVALID);
+        }
     }
-    
+
     /**
      * Stop the instance manager.
      */
     public synchronized void stop() {
-        if (m_state == STOPPED) {
-            return;
-        } // Instance already stopped
-        
+        if (m_state == STOPPED) { return; } // Instance already stopped
 
         setState(INVALID);
-        
+
         if (m_handler != null) {
             m_handler.stop();
         }
-        
+
         // Stop all the handlers
         for (int i = m_handlers.length - 1; i > -1; i--) {
             m_handlers[i].removeInstanceStateListener(this);
@@ -130,13 +125,13 @@
         }
 
         m_state = STOPPED;
-        if (m_instanceListeners != null) {
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+        if (m_listeners != null) {
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, STOPPED);
             }
         }
     }
-    
+
     /** 
      * Dispose the instance.
      * @see org.apache.felix.ipojo.ComponentInstance#dispose()
@@ -145,7 +140,7 @@
         super.dispose();
         m_handler = null;
     }
-    
+
     /**
      * Kill the current instance.
      * Only the factory of this instance can call this method.
@@ -155,4 +150,31 @@
         m_handler = null;
     }
 
+    /**
+     * 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
+            if (!m_handler.getValidity()) { return; }
+            for (int i = 0; i < m_handlers.length; i++) {
+                if (m_handlers[i].getState() != VALID) { return; }
+            }
+            setState(VALID);
+            return;
+        }
+    }
+
 }
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
deleted file mode 100644
index 78d3434..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
+++ /dev/null
@@ -1,73 +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 org.apache.felix.ipojo.composite.instance.InstanceHandler;
-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;
-import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
-import org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler;
-import org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler;
-import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * iPOJO Configuration : Default Log Level - Available (core) handlers.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class IPojoConfiguration {
-
-    /**
-     * 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.
-     */
-    public static final Class[] INTERNAL_HANDLERS = new Class[] { 
-        DependencyHandler.class, 
-        ProvidedServiceHandler.class, 
-        ConfigurationHandler.class,
-        LifecycleCallbackHandler.class,
-        ControllerHandler.class,
-        ArchitectureHandler.class
-    };
-
-    /**
-     * Available composite handlers in the iPOJO bundle.
-     */
-    public static final Class[] INTERNAL_COMPOSITE_HANDLERS = new Class[] { 
-        ServiceInstantiatorHandler.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 a1e2e53..09bfcdf 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
@@ -54,25 +54,24 @@
     /**
      * Constructor. Used when the service context = the bundle context
      * 
-     * @param bc : bundle context
+     * @param context : bundle context
      */
-    public IPojoContext(BundleContext bc) {
-        m_bundleContext = bc;
+    public IPojoContext(BundleContext context) {
+        m_bundleContext = context;
     }
 
     /**
      * Constructor. Used when the service context and the bundle context are
      * different
      * 
-     * @param bc : bundle context
-     * @param sc : service context
+     * @param bundleContext : bundle context
+     * @param serviceContext : service context
      */
-    public IPojoContext(BundleContext bc, ServiceContext sc) {
-        m_bundleContext = bc;
-        m_serviceContext = sc;
+    public IPojoContext(BundleContext bundleContext, ServiceContext serviceContext) {
+        m_bundleContext = bundleContext;
+        m_serviceContext = serviceContext;
     }
 
-   
     /**
      * Add a bundle listener.
      * @param listener : the listener to add
@@ -119,7 +118,6 @@
         }
     }
 
-
     /**
      * Create a Filter object.
      * @param filter : the string form of the LDAP filter to create
@@ -158,12 +156,12 @@
 
     /**
      * Get the bundle object with the given id.
-     * @param id : bundle id
+     * @param bundleId : bundle id
      * @return the bundle object
      * @see org.osgi.framework.BundleContext#getBundle(long)
      */
-    public Bundle getBundle(long id) {
-        return m_bundleContext.getBundle(id);
+    public Bundle getBundle(long bundleId) {
+        return m_bundleContext.getBundle(bundleId);
     }
 
     /**
@@ -175,7 +173,6 @@
         return m_bundleContext.getBundles();
     }
 
-
     /**
      * Get a data file.
      * @param filename : File name.
@@ -340,7 +337,7 @@
             return m_serviceContext.ungetService(reference);
         }
     }
-    
+
     /**
      * Get the global context, i.e. the bundle context of the factory.
      * @return the global bundle context.
@@ -348,15 +345,12 @@
     public BundleContext getGlobalContext() {
         return m_bundleContext;
     }
-    
+
     /**
      * Get the service context, i.e. the composite context.
      * @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/IPojoFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
new file mode 100644
index 0000000..44ae438
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
@@ -0,0 +1,829 @@
+/* 
+ * 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.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+/**
+ * This class abstracts iPOJO factories.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class IPojoFactory implements Factory, ManagedServiceFactory {
+
+    /**
+     * List of the managed instance name. This list is shared by all factories.
+     */
+    protected static List m_instancesName = new ArrayList();
+
+    /**
+     * Component-Type description exposed by the factory service.
+     */
+    protected ComponentTypeDescription m_componentDesc;
+
+    /**
+     * List of the managed instance managers. The key of this map is the name (i.e. instance names) of the created instance
+     */
+    protected Map m_componentInstances = new HashMap();
+
+    /**
+     * Component Type provided by this factory.
+     */
+    protected Element m_componentMetadata;
+
+    /**
+     * The bundle context reference.
+     */
+    protected BundleContext m_context = null;
+
+    /**
+     * Factory Name. Could be the component class name if the factory name is not set.
+     */
+    protected String m_factoryName;
+
+    /**
+     * List of required handler.
+     */
+    protected List m_requiredHandlers = new ArrayList();
+
+    /**
+     * List of listeners.
+     */
+    protected List m_listeners = new ArrayList(2);
+
+    /**
+     * Logger for the factory (and all component instance).
+     */
+    protected Logger m_logger;
+
+    /**
+     * Is the factory public (expose as a service).
+     */
+    protected boolean m_isPublic;
+
+    /**
+     * Service Registration of this factory (Factory & ManagedServiceFactory).
+     */
+    protected ServiceRegistration m_sr;
+
+    /**
+     * Factory state.
+     */
+    protected int m_state = Factory.INVALID;
+
+    /**
+     * Index used to generate instance name if not set.
+     */
+    private long m_index = 0;
+
+    /**
+     * Flag indicating if this factory has already a computed description or not.
+     */
+    private boolean m_described;
+
+    /**
+     * Constructor.
+     * @param context : bundle context of the bundle containing the factory.
+     * @param metadata : description of the component type.
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
+     */
+    public IPojoFactory(BundleContext context, Element metadata) throws ConfigurationException {
+        m_context = context;
+        m_componentMetadata = metadata;
+        m_factoryName = getFactoryName();
+        String fac = metadata.getAttribute("factory");
+        m_isPublic = fac == null || !fac.equalsIgnoreCase("false");
+        m_logger = new Logger(m_context, m_factoryName);
+        m_requiredHandlers = getRequiredHandlerList();
+    }
+
+    public ComponentTypeDescription getComponentTypeDescription() {
+        return new ComponentTypeDescription(this);
+    }
+
+    /**
+     * Add a factory listener.
+     * @param listener : the factory listener to add.
+     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void addFactoryStateListener(FactoryStateListener listener) {
+        synchronized (m_listeners) {
+            m_listeners.add(listener);
+        }
+    }
+
+    /**
+     * Get the logger used by instances of he current factory.
+     * @return the factory logger.
+     */
+    public Logger getLogger() {
+        return m_logger;
+    }
+
+    /**
+     * Compute the factory name.
+     * @return the factory name.
+     */
+    public abstract String getFactoryName();
+
+    /**
+     * Compute the required handler list.
+     * @return the required handler list
+     */
+    public abstract List getRequiredHandlerList();
+
+    /**
+     * Create an instance.
+     * @param config : instance configuration
+     * @param context : ipojo context to use
+     * @param handlers : handler array to use
+     * @return the new component instance.
+     * @throws ConfigurationException : occurs when the instance creation failed during the configuration process.
+     */
+    public abstract ComponentInstance createInstance(Dictionary config, IPojoContext context, HandlerManager[] handlers)
+            throws ConfigurationException;
+
+    /**
+     * 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 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 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, // NOPMD
+            MissingHandlerException, ConfigurationException {
+        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 name = null;
+        if (configuration.get("name") == null) {
+            name = generateName();
+            configuration.put("name", name);
+        } else {
+            name = (String) configuration.get("name");
+            if (m_instancesName.contains(name)) {
+                m_logger.log(Logger.ERROR, "The configuration is not acceptable : Name already used");
+                throw new UnacceptableConfiguration("Name already used : " + name);
+            }
+        }
+
+        IPojoContext context = null;
+        if (serviceContext == null) {
+            context = new IPojoContext(m_context);
+        } else {
+            context = new IPojoContext(m_context, serviceContext);
+        }
+
+        HandlerManager[] handlers = new HandlerManager[m_requiredHandlers.size()];
+        for (int i = 0; i < handlers.length; i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            handlers[i] = getHandler(req, serviceContext);
+        }
+        try {
+            ComponentInstance instance = createInstance(configuration, context, handlers);
+            m_instancesName.add(name);
+            m_componentInstances.put(name, instance);
+            return instance;
+        } catch (ConfigurationException e) {
+            m_logger.log(Logger.ERROR, e.getMessage());
+            throw new ConfigurationException(e.getMessage(), m_factoryName);
+        }
+    }
+
+    public BundleContext getBundleContext() {
+        return m_context;
+    }
+
+    /**
+     * Get the factory class name.
+     * @return the factory classname.
+     * @see org.apache.felix.ipojo.Factory#getClassName()
+     */
+    public abstract String getClassName();
+
+    /**
+     * Get the component type description.
+     * @return the component type description object. Null if not already computed.
+     */
+    public ComponentTypeDescription getComponentDescription() {
+        return m_componentDesc;
+    }
+
+    /**
+     * Get the component type description (Element-Attribute form).
+     * @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 " + m_factoryName, "");
+        }
+        return m_componentDesc.getDescription();
+    }
+
+    /**
+     * Compute the list of missing handlers.
+     * @return list of missing handlers.
+     * @see org.apache.felix.ipojo.Factory#getMissingHandlers()
+     */
+    public List getMissingHandlers() {
+        List list = new ArrayList();
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (req.getReference() == null) {
+                list.add(req.getFullName());
+            }
+        }
+        return list;
+    }
+
+    public String getName() {
+        return m_factoryName;
+    }
+
+    /**
+     * Get the list of required handlers.
+     * @return list of required handlers.
+     * @see org.apache.felix.ipojo.Factory#getRequiredHandlers()
+     */
+    public List getRequiredHandlers() {
+        List list = new ArrayList();
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            list.add(req.getFullName());
+        }
+        return list;
+    }
+
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * Check if the configuration is acceptable.
+     * @param conf : the configuration to test.
+     * @return true if the configuration is acceptable.
+     * @see org.apache.felix.ipojo.Factory#isAcceptable(java.util.Dictionary)
+     */
+    public boolean isAcceptable(Dictionary conf) {
+        try {
+            checkAcceptability(conf);
+        } catch (MissingHandlerException e) {
+            return false;
+        } catch (UnacceptableConfiguration e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Check if the configuration is acceptable.
+     * @param conf : the configuration to test.
+     * @throws UnacceptableConfiguration occurs if the configuration is unacceptable.
+     * @throws MissingHandlerException occurs if an handler is missing.
+     */
+    public void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
+        if (m_state == Factory.INVALID) {
+            throw new MissingHandlerException(getMissingHandlers());
+        }
+
+        // Check that the configuration does not override immutable properties.
+        PropertyDescription[] props = m_componentDesc.getProperties();
+        for (int i = 0; i < props.length; i++) {
+            // Is the property immutable
+            if (props[i].isImmutable() && conf.get(props[i].getName()) != null) {
+                throw new UnacceptableConfiguration("The property " + props[i] + " cannot be overide : immutable property"); // The instance
+                // configuration try
+                // to override an
+                // immutable property.
+            }
+            // Is the property required.
+            if (props[i].getValue() == null && conf.get(props[i].getName()) == null) {
+                throw new UnacceptableConfiguration("The property " + props[i].getName() + " is missing"); // The property must be set.
+            }
+        }
+    }
+
+    /**
+     * 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");
+        }
+        String name = (String) properties.get("name");
+        ComponentInstance instance = (ComponentInstance) m_componentInstances.get(name);
+
+        if (instance == null) {
+            return; // The instance does not exist.
+        } else {
+            checkAcceptability(properties); // Test if the configuration is acceptable
+            instance.reconfigure(properties); // re-configure the component
+        }
+    }
+
+    /**
+     * Remove a factory listener.
+     * @param listener : the factory listener to remove.
+     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void removeFactoryStateListener(FactoryStateListener listener) {
+        synchronized (m_listeners) {
+            m_listeners.remove(listener);
+        }
+    }
+
+    /**
+     * Stopping method. This method is call when the factory is stopping.
+     */
+    public abstract void stopping();
+
+    /**
+     * Stop all the instance managers.
+     */
+    public synchronized void stop() {
+        if (m_sr != null) {
+            m_sr.unregister();
+            m_sr = null;
+        }
+
+        stopping();
+
+        if (m_state == VALID) {
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
+            }
+        }
+        m_state = INVALID;
+
+        // Dispose created instances.
+        Set col = m_componentInstances.keySet();
+        String[] keys = (String[]) col.toArray(new String[col.size()]);
+        for (int i = 0; i < keys.length; i++) {
+            ComponentInstance instance = (ComponentInstance) m_componentInstances.get(keys[i]);
+            if (instance.getState() != ComponentInstance.DISPOSED) {
+                instance.dispose();
+            }
+        }
+
+        // Release each handler
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            ((RequiredHandler) m_requiredHandlers.get(i)).unRef();
+        }
+
+        m_described = false;
+        m_componentDesc = null;
+        m_componentInstances.clear();
+    }
+
+    /**
+     * Destroy the factory. The factory cannot be restarted.
+     * Only the extender can call this method.
+     */
+    void dispose() {
+        stop();
+        m_componentMetadata = null;
+        m_componentInstances = null;
+        m_context = null;
+        m_requiredHandlers = null;
+        m_listeners = null;
+        m_logger = null;
+    }
+
+    /**
+     * Starting method. This method is called when the factory is starting.
+     */
+    public abstract void starting();
+
+    /**
+     * Start the factory.
+     */
+    public synchronized void start() {
+        if (m_described) { // Already started.
+            return;
+        }
+
+        m_componentDesc = getComponentTypeDescription();
+
+        starting();
+
+        computeFactoryState();
+
+        if (m_isPublic) {
+            // Exposition of the factory service
+            m_sr =
+                    m_context.registerService(new String[] { Factory.class.getName(), ManagedServiceFactory.class.getName() }, this, m_componentDesc
+                            .getPropertiesToPublish());
+        }
+    }
+
+    /**
+     * Create of update an instance.
+     * @param name : name of the instance
+     * @param properties : configuration of the instance
+     * @throws org.osgi.service.cm.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 name, Dictionary properties) throws org.osgi.service.cm.ConfigurationException {
+        InstanceManager instance = (InstanceManager) m_componentInstances.get(name);
+        if (instance == null) {
+            try {
+                properties.put("name", name); // 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 org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            } catch (MissingHandlerException e) {
+                m_logger.log(Logger.ERROR, "Handler not available : " + e.getMessage());
+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            } catch (ConfigurationException e) {
+                m_logger.log(Logger.ERROR, "The Component Type metadata are not correct : " + e.getMessage());
+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            }
+        } else {
+            try {
+                properties.put("name", name); // 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 org.osgi.service.cm.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 org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Delete an instance.
+     * @param name : name of the instance to delete
+     * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
+     */
+    public synchronized void deleted(String name) {
+        m_instancesName.remove(name);
+        ComponentInstance instance = (ComponentInstance) m_componentInstances.remove(name);
+        if (instance != null) {
+            instance.dispose();
+        }
+    }
+
+    /**
+     * Callback called by instance when disposed.
+     * @param instance : the destroyed instance
+     */
+    public void disposed(ComponentInstance instance) {
+        String name = instance.getInstanceName();
+        m_instancesName.remove(name);
+        m_componentInstances.remove(name);
+    }
+
+    /**
+     * Compute the component type description. The factory must be valid when calling this method.
+     */
+    protected void computeDescription() {
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            Handler handler = getHandler(req, null).getHandler();
+            try {
+                handler.setFactory(this);
+                handler.initializeComponentFactory(m_componentDesc, m_componentMetadata);
+                ((Pojo) handler).getComponentInstance().dispose();
+            } catch (org.apache.felix.ipojo.ConfigurationException e) {
+                ((Pojo) handler).getComponentInstance().dispose();
+                m_logger.log(Logger.ERROR, e.getMessage());
+                stop();
+                throw new IllegalStateException(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Compute factory state.
+     */
+    protected void computeFactoryState() {
+        boolean isValid = true;
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (req.getReference() == null) {
+                isValid = false;
+                break;
+            }
+
+        }
+
+        if (isValid) {
+            if (m_state == INVALID) {
+
+                if (!m_described) {
+                    computeDescription();
+                    m_described = true;
+                }
+
+                m_state = VALID;
+                if (m_sr != null) {
+                    m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
+                }
+                for (int i = 0; i < m_listeners.size(); i++) {
+                    ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, VALID);
+                }
+                return;
+            }
+        } else {
+            if (m_state == VALID) {
+                m_state = INVALID;
+
+                // Notify listeners.
+                for (int i = 0; i < m_listeners.size(); i++) {
+                    ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
+                }
+
+                // Dispose created instances.
+                Set col = m_componentInstances.keySet();
+                String[] keys = (String[]) col.toArray(new String[col.size()]);
+                for (int i = 0; i < keys.length; i++) {
+                    ComponentInstance instance = (ComponentInstance) m_componentInstances.get(keys[i]);
+                    if (instance.getState() != ComponentInstance.DISPOSED) {
+                        instance.dispose();
+                    }
+                    m_instancesName.remove(instance.getInstanceName());
+                }
+
+                m_componentInstances.clear();
+
+                if (m_sr != null) {
+                    m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
+                }
+
+                return;
+            }
+        }
+    }
+
+    /**
+     * Check if the given handler identifier and the service reference can match.
+     * @param req : the handler identifier.
+     * @param ref : the service reference.
+     * @return true if the service reference can fulfill the handler requirement
+     */
+    protected boolean match(RequiredHandler req, ServiceReference ref) {
+        String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);
+        String namespace = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);
+        if (HandlerFactory.IPOJO_NAMESPACE.equals(namespace)) {
+            return name.equals(req.getName()) && req.getNamespace() == null;
+        }
+        return name.equals(req.getName()) && namespace.equals(req.getNamespace());
+    }
+
+    /**
+     * Return the handler object for the given required handler. The handler is instantiated in the given service context.
+     * @param req : handler to create.
+     * @param context : service context in which create the handler (instance context).
+     * @return the Handler object.
+     */
+    protected HandlerManager getHandler(RequiredHandler req, ServiceContext context) {
+        try {
+            return (HandlerManager) req.getFactory().createComponentInstance(null, context);
+        } catch (MissingHandlerException e) {
+            m_logger.log(Logger.ERROR, "The creation of the handler " + req.getFullName() + " has failed: " + e.getMessage());
+            stop();
+            return null;
+        } catch (UnacceptableConfiguration e) {
+            m_logger.log(Logger.ERROR, "The creation of the handler "
+                    + req.getFullName()
+                    + " has failed (UnacceptableConfiguration): "
+                    + e.getMessage());
+            stop();
+            return null;
+        } catch (org.apache.felix.ipojo.ConfigurationException e) {
+            m_logger.log(Logger.ERROR, "The configuration of the handler "
+                    + req.getFullName()
+                    + " has failed (ConfigurationException): "
+                    + e.getMessage());
+            stop();
+            return null;
+        }
+    }
+
+    /**
+     * Helping method generating a new unique name.
+     * @return an non already used name
+     */
+    protected synchronized String generateName() {
+        String name = m_factoryName + "-" + m_index;
+        while (m_instancesName.contains(name)) {
+            m_index = m_index + 1;
+            name = m_factoryName + "-" + m_index;
+        }
+        return name;
+    }
+
+    /**
+     * Structure storing required handlers.
+     */
+    protected class RequiredHandler implements Comparable {
+        /**
+         * Factory to create this handler.
+         */
+        private HandlerFactory m_factory;
+
+        /**
+         * Handler name.
+         */
+        private String m_name;
+
+        /**
+         * Handler start level.
+         */
+        private int m_level = Integer.MAX_VALUE;
+
+        /**
+         * Handler namespace.
+         */
+        private String m_namespace;
+
+        /**
+         * Service Reference of the handler factory.
+         */
+        private ServiceReference m_reference;
+
+        /**
+         * Constructor.
+         * @param name : handler name.
+         * @param namespace : handler namespace.
+         */
+        public RequiredHandler(String name, String namespace) {
+            m_name = name;
+            m_namespace = namespace;
+        }
+
+        /**
+         * Equals method. Two handlers are equals if they have same name and namespace or they share the same service reference.
+         * @param object : 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 object) {
+            if (object instanceof RequiredHandler) {
+                RequiredHandler req = (RequiredHandler) object;
+                if (m_namespace == null) {
+                    return req.m_name.equalsIgnoreCase(m_name) && req.m_namespace == null;
+                } else {
+                    return req.m_name.equalsIgnoreCase(m_name) && m_namespace.equalsIgnoreCase(req.m_namespace);
+                }
+            } else {
+                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 HandlerFactory getFactory() {
+            if (m_reference == null) {
+                return null;
+            }
+            if (m_factory == null) {
+                m_factory = (HandlerFactory) m_context.getService(getReference());
+            }
+            return m_factory;
+        }
+
+        /**
+         * Get the handler full name (namespace:name).
+         * @return the handler full name
+         */
+        public String getFullName() {
+            if (m_namespace == null) {
+                return HandlerFactory.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;
+        }
+
+        public int getLevel() {
+            return m_level;
+        }
+
+        /**
+         * Release the reference of the used factory.
+         */
+        public void unRef() {
+            if (m_reference != null) {
+                // m_context.ungetService(m_reference); // Will be unget automatically
+                m_factory = null;
+                m_reference = null;
+            }
+        }
+
+        /**
+         * 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) {
+            m_reference = ref;
+            Integer level = (Integer) m_reference.getProperty(Handler.HANDLER_LEVEL_PROPERTY);
+            if (level != null) {
+                m_level = level.intValue();
+            }
+        }
+
+        /**
+         * Start level Comparison. This method is used to sort the handler array.
+         * @param object : object on which compare.
+         * @return -1, 0, +1 according to the comparison of their start level.
+         * @see java.lang.Comparable#compareTo(java.lang.Object)
+         */
+        public int compareTo(Object object) {
+            if (object instanceof RequiredHandler) {
+                RequiredHandler req = (RequiredHandler) object;
+                if (this.m_level == req.m_level) {
+                    return 0;
+                } else if (this.m_level < req.m_level) {
+                    return -1;
+                } else {
+                    return +1;
+                }
+            }
+            return 0;
+        }
+    }
+
+}
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 c356b2a..7333161 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
@@ -18,51 +18,238 @@
  */
 package org.apache.felix.ipojo;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 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.ServiceReference;
 
 /**
- * An instance creator aims to create instances and to track their factories.
- * It's allow to create instance from outside factories.
- * 
+ * An instance creator aims to create instances and to track their factories. It's allow to create instance from outside factories.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceCreator implements TrackerCustomizer, FactoryStateListener {
-    /**
-     * Bundle Context.
-     */
-    private BundleContext m_context;
+public class InstanceCreator implements FactoryStateListener {
 
     /**
      * 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
-     * information to create an instance and to track the factory.
+     * Configurations to create and maintains.
      */
-    private class ManagedConfiguration {
+    private List m_idle = new ArrayList();
+
+    /**
+     * Map storing created instance. [AbstractFactory, List [ManagedInstance]]
+     */
+    private Map m_attached = new HashMap();
+
+    /**
+     * Abstract Factory list.
+     */
+    private List m_factories = new ArrayList();
+
+    /**
+     * Constructor.
+     * @param context : iPOJO bundle context.
+     */
+    public InstanceCreator(BundleContext context) {
+        m_logger = new Logger(context, "iPOJO Instance Creator");
+    }
+
+    /**
+     * Add an instance to manage.
+     * @param instance : instance configuration
+     * @param bundle : bundle id declaring the instance
+     */
+    synchronized void addInstance(Dictionary instance, long bundle) {
+        ManagedInstance managed = new ManagedInstance(instance, bundle);
+        for (int i = 0; i < m_factories.size(); i++) {
+            IPojoFactory factory = (IPojoFactory) m_factories.get(i);
+            if (factory.getState() == Factory.VALID && managed.match(factory)) {
+                managed.create(factory);
+                List list = (List) m_attached.get(factory);
+                if (list == null) {
+                    list = new ArrayList();
+                    list.add(managed);
+                    m_attached.put(factory, list);
+                    // Subscribe to the factory state change
+                    factory.addFactoryStateListener(this);
+                } else {
+                    list.add(managed);
+                }
+                return;
+            }
+        }
+        // If there is no matching factory, add the instance to the idle list
+        m_idle.add(managed);
+    }
+
+    /**
+     * Dispose and stop to manage all instances declared by the given bundle.
+     * @param bundle : bundle.
+     */
+    void removeInstancesFromBundle(long bundle) {
+        // Disposes instance from attached instances
+        Collection col = m_attached.keySet();
+        Iterator iterator = col.iterator();
+        List instanceToRemove = new ArrayList();
+        List factoryToRemove = new ArrayList();
+        while (iterator.hasNext()) {
+            IPojoFactory factory = (IPojoFactory) iterator.next();
+            List list = (List) m_attached.get(factory);
+            for (int i = 0; i < list.size(); i++) {
+                ManagedInstance managed = (ManagedInstance) list.get(i);
+                if (managed.m_bundleId == bundle) {
+                    managed.dispose();
+                    instanceToRemove.add(managed);
+                }
+            }
+            if (!instanceToRemove.isEmpty()) {
+                list.removeAll(instanceToRemove);
+                if (list.isEmpty()) {
+                    factory.removeFactoryStateListener(this);
+                    factoryToRemove.add(factory);
+                }
+            }
+        }
+
+        for (int i = 0; i < factoryToRemove.size(); i++) {
+            m_attached.remove(factoryToRemove.get(i));
+        }
+
+        // Delete idle instances
+        instanceToRemove.clear();
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.m_bundleId == bundle) {
+                instanceToRemove.add(managed);
+            }
+        }
+        m_idle.removeAll(instanceToRemove);
+    }
+
+    /**
+     * A new factory appears.
+     * @param factory : the new factory.
+     */
+    public synchronized void addFactory(IPojoFactory factory) {
+        List createdInstances = new ArrayList(1);
+        m_factories.add(factory);
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.match(factory)) {
+                // We have to subscribe to the factory.
+                factory.addFactoryStateListener(this);
+                if (factory.getState() == Factory.VALID) {
+                    managed.create(factory);
+                    List list = (List) m_attached.get(factory);
+                    if (list == null) {
+                        list = new ArrayList();
+                        list.add(managed);
+                        m_attached.put(factory, list);
+                    } else {
+                        list.add(managed);
+                    }
+                    createdInstances.add(managed);
+                }
+            }
+        }
+        if (!createdInstances.isEmpty()) {
+            m_idle.removeAll(createdInstances);
+        }
+    }
+
+    /**
+     * A factory is leaving.
+     * @param factory : the leaving factory
+     */
+    void removeFactory(IPojoFactory factory) {
+        factory.removeFactoryStateListener(this);
+        m_factories.remove(factory);
+        onInvalidation(factory);
+        m_attached.remove(factory);
+    }
+
+    /**
+     * The given factory becomes valid.
+     * @param factory : the factory becoming valid.
+     */
+    private void onValidation(IPojoFactory factory) {
+        List toRemove = new ArrayList();
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.match(factory)) {
+                managed.create(factory);
+                List list = (List) m_attached.get(factory);
+                if (list == null) {
+                    list = new ArrayList();
+                    list.add(managed);
+                    m_attached.put(factory, list);
+                } else {
+                    list.add(managed);
+                }
+                toRemove.add(managed);
+            }
+        }
+        if (!toRemove.isEmpty()) {
+            m_idle.removeAll(toRemove);
+        }
+    }
+
+    /**
+     * The given factory becomes invalid.
+     * @param factory : factory which becomes invalid.
+     */
+    private void onInvalidation(IPojoFactory factory) {
+        List instances = (List) m_attached.remove(factory);
+        if (instances != null) {
+            for (int i = 0; i < instances.size(); i++) {
+                ManagedInstance managed = (ManagedInstance) instances.get(i);
+                managed.dispose();
+                m_idle.add(managed);
+            }
+        }
+    }
+
+    /**
+     * 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) {
+            onValidation((IPojoFactory) factory);
+        } else {
+            onInvalidation((IPojoFactory) factory);
+        }
+    }
+
+    /**
+     * This structure aims to manage a configuration. It stores all necessary information to create an instance and to track the factory.
+     */
+    private class ManagedInstance {
         /**
          * Configuration of the instance to create.
          */
         private Dictionary m_configuration;
 
         /**
-         * Factory name.
+         * Bundle which create the instance.
          */
-        private String m_factoryName;
+        private long m_bundleId;
+
+        /**
+         * Factory used to create the instance.
+         */
+        private IPojoFactory m_factory;
 
         /**
          * Created instance.
@@ -71,27 +258,20 @@
 
         /**
          * Constructor.
-         * 
          * @param conf : the configuration to create.
+         * @param bundle : the bundle in which the instance is declared.
          */
-        ManagedConfiguration(Dictionary conf) {
+        ManagedInstance(Dictionary conf, long bundle) {
             m_configuration = conf;
-        }
-
-        /**
-         * Return the managed configuration.
-         * @return the configuration.
-         */
-        Dictionary getConfiguration() {
-            return m_configuration;
+            m_bundleId = bundle;
         }
 
         /**
          * Return the used factory name.
          * @return the factory
          */
-        String getFactory() {
-            return m_factoryName;
+        IPojoFactory getFactory() {
+            return m_factory;
         }
 
         /**
@@ -103,215 +283,59 @@
         }
 
         /**
-         * Set the factory name.
-         * 
-         * @param name : the factory name.
+         * Test if the given factory match with the factory required by this instance. A factory matches if its name or its class name is equals to
+         * the 'component' property of the instance. Then the acceptability of the configuration is checked.
+         * @param factory : the factory to confront against the current instance.
+         * @return true if the factory match.
          */
-        void setFactory(String name) {
-            m_factoryName = name;
+        public boolean match(IPojoFactory factory) {
+            // Test factory name (and classname)
+            String component = (String) m_configuration.get("component");
+            if (factory.getName().equals(component) || factory.getClassName().equalsIgnoreCase(component)) {
+                // Test factory accessibility
+                if (factory.m_isPublic || factory.getBundleContext().getBundle().getBundleId() == m_bundleId) {
+                    // Test the configuration validity.
+                    if (factory.isAcceptable(m_configuration)) {
+                        return true;
+                    } else {
+                        m_logger.log(Logger.ERROR, "An instance can be bound to a matching factory, however the configuration seems unacceptable : "
+                                + m_configuration);
+                    }
+                }
+            }
+            return false;
         }
 
         /**
-         * Set the instance object.
-         * 
-         * @param instance : the instance
+         * Create the instance by using the given factory.
+         * @param factory : the factory to use to create the instance. The factory must match.
          */
-        void setInstance(ComponentInstance instance) {
-            m_instance = instance;
-        }
-    }
-
-    /**
-     * Configurations to create and maintains.
-     */
-    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, 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");
-
-            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;
-                }
+        public void create(IPojoFactory factory) {
+            try {
+                m_factory = factory;
+                m_instance = m_factory.createComponentInstance(m_configuration);
+            } catch (UnacceptableConfiguration e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
+            } catch (MissingHandlerException e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
+            } catch (ConfigurationException e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
             }
         }
-        
-        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;
-        } 
-    }
 
-    /**
-     * Create an instance using the given factory and the given configuration.
-     * 
-     * @param fact : the factory name to used.
-     * @param config : the configuration.
-     */
-    private void createInstance(Factory fact, ManagedConfiguration config) {
-        Dictionary conf = config.getConfiguration();
-        try {
-            config.setInstance(fact.createComponentInstance(conf));
-            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);
-            stop();
-        } catch (MissingHandlerException e) {
-            m_logger.log(Logger.ERROR, "The instance creation has failed, at least one handler is missing", e);
-            stop();
-        } catch (ConfigurationException e) {
-            m_logger.log(Logger.ERROR, "The instance creation has failed, an error during the configuration has occured", e);
-            stop();
-        }
-    }
-
-    /**
-     * Stop all created instances.
-     */
-    public synchronized void stop() {
-        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();
+        /**
+         * Dispose the current instance.
+         */
+        public void dispose() {
+            if (m_instance != null) {
+                m_instance.dispose();
             }
-            m_configurations[i].setInstance(null);
-            m_configurations[i].setFactory(null);
+            m_instance = null;
+            m_factory = 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 matching service has been added to the tracker.
-     * Nothing to do, as all action are computed in the adding method.
-     * @param ref : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference ref) { }
-
-    /**
-     * 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) { }
-
-    /**
-     * 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) {
-        String name = (String) ref.getProperty("factory.name");
-        if (name == null) { return; }
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getFactory() != null && m_configurations[i].getFactory().equals(name)) {
-                if (m_configurations[i].getInstance() != null) {
-                    m_configurations[i].getInstance().dispose();
-                    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 b310ece..01172df 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
@@ -19,7 +19,9 @@
 package org.apache.felix.ipojo;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashMap;
@@ -35,13 +37,10 @@
 import org.osgi.framework.BundleContext;
 
 /**
- * The instance manager class manages one instance of a component type. It
- * manages component lifecycle, component instance creation and handlers.
- * 
+ * The instance manager class manages one instance of a component type. It manages component lifecycle, component instance creation and handlers.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class InstanceManager implements ComponentInstance, InstanceStateListener {
-
     /**
      * Name of the component instance.
      */
@@ -51,7 +50,7 @@
      * Name of the component type implementation class.
      */
     protected String m_className;
-    
+
     /**
      * Handler list.
      */
@@ -61,12 +60,12 @@
      * Component state (STOPPED at the beginning).
      */
     protected int m_state = STOPPED;
-    
+
     /**
      * Instance State Listener List.
      */
-    protected List m_instanceListeners = null;
-    
+    protected List m_listeners = null;
+
     /**
      * Parent factory (ComponentFactory).
      */
@@ -78,12 +77,12 @@
     private BundleContext m_context;
 
     /**
-     * Map [field, handler list] storing handlers interested by the field.
+     * Map [field, field interceptor list] storing handlers interested by the field.
      */
-    private Map m_fieldRegistration = new HashMap();
-    
+    private Map m_fieldRegistration;
+
     /**
-     * Map [method identifier, handler list] storing handlers interested by the method.
+     * Map [method identifier, method interceptor list] storing handlers interested by the method.
      */
     private Map m_methodRegistration;
 
@@ -95,78 +94,89 @@
     /**
      * Instances of the components.
      */
-    private Object[] m_pojoObjects = null;
+    private List m_pojoObjects;
 
-   /**
-    * Is the component instance state changing?
-    */
-    private boolean m_inTransition = false;
-    
     /**
-     * Queue of stored state changed. 
+     * Factory method. Contains the name of the static method used to create POJO objects.
+     */
+    private String m_factoryMethod = null;
+
+    /**
+     * Is the component instance state changing?
+     */
+    private boolean m_inTransition = false;
+
+    /**
+     * Queue of stored state changed.
      */
     private List m_stateQueue = new ArrayList();
-    
+
     /**
      * Map of [field, value], storing POJO field value.
      */
-    private Map m_map = new HashMap();
+    private Map m_fields = new HashMap();
+
+    /**
+     * Map method [id=>method].
+     */
+    private Map m_methods = new HashMap();
 
     /**
      * Construct a new Component Manager.
-     * 
      * @param factory : the factory managing the instance manager
-     * @param bc : the bundle context to give to the instance
+     * @param context : the bundle context to give to the instance
      * @param handlers : handlers array
      */
-    public InstanceManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
+    public InstanceManager(ComponentFactory factory, BundleContext context, HandlerManager[] handlers) {
         m_factory = factory;
-        m_context = bc;
+        m_context = context;
         m_handlers = handlers;
     }
 
     /**
-     * Configure the instance manager. Stop the existing handler, clear the
-     * handler list, change the metadata, recreate the handlers
-     * 
-     * @param cm : the component type metadata
+     * Configure the instance manager. Stop the existing handler, clear the handler list, change the metadata, recreate the handlers
+     * @param metadata : 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) throws ConfigurationException {
-        m_className = cm.getAttribute("className");
-        
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        m_className = metadata.getAttribute("className");
+
         // Add the name
         m_name = (String) configuration.get("name");
-        
+
+        // Get the factory method if presents.
+        m_factoryMethod = (String) metadata.getAttribute("factory-method");
+
         // Create the standard handlers and add these handlers to the list
         for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].init(this, cm, configuration);
+            m_handlers[i].init(this, metadata, configuration);
         }
     }
 
     /**
-     * Get the description of the current instance. 
+     * Get the description of the current instance.
      * @return the instance description.
      * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
      */
     public InstanceDescription getInstanceDescription() {
         int componentState = getState();
-        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
+        InstanceDescription desc =
+                new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
 
         if (m_pojoObjects != null) {
-            String[] objects = new String[m_pojoObjects.length];
-            for (int i = 0; i < m_pojoObjects.length; i++) {
-                objects[i] = m_pojoObjects[i].toString();
+            String[] objects = new String[m_pojoObjects.size()];
+            for (int i = 0; i < m_pojoObjects.size(); i++) {
+                objects[i] = m_pojoObjects.get(i).toString();
             }
-            instanceDescription.setCreatedObjects(objects);
+            desc.setCreatedObjects(objects);
         }
 
         Handler[] handlers = getRegistredHandlers();
         for (int i = 0; i < handlers.length; i++) {
-            instanceDescription.addHandler(handlers[i].getDescription());
+            desc.addHandler(handlers[i].getDescription());
         }
-        return instanceDescription;
+        return desc;
     }
 
     /**
@@ -174,22 +184,21 @@
      * @return the handler array of plugged handlers.
      */
     public Handler[] getRegistredHandlers() {
-        Handler[] h = new Handler[m_handlers.length];
+        Handler[] handler = new Handler[m_handlers.length];
         for (int i = 0; i < m_handlers.length; i++) {
-            h[i] = m_handlers[i].getHandler();
+            handler[i] = m_handlers[i].getHandler();
         }
-        return h;
+        return handler;
     }
 
     /**
      * Return a specified handler.
-     * 
      * @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++) {
-            HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getInstance().getFactory();
+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getHandlerManager().getFactory();
             if (fact.getHandlerName().equals(name)) {
                 return m_handlers[i].getHandler();
             }
@@ -198,24 +207,83 @@
     }
 
     /**
+     * Give access to a field value to the first created pojo.
+     * This method process by analyzing both managed fields and pojo fields (by reflection).
+     * If no pojo were already created try only on managed fields.
+     * @param fieldName : field name.
+     * @return the field value, null is returned if the value is managed and not already set.
+     */
+    public synchronized Object getFieldValue(String fieldName) {
+        if (m_pojoObjects == null) {
+            return getFieldValue(fieldName, null);
+        } else {
+            return getFieldValue(fieldName, m_pojoObjects.get(0)); // Use the first pojo.
+        }
+    }
+
+    /**
+     * Give access to a field value to the given created pojo.
+     * This method process by analyzing both managed fields and pojo fields (by reflection).
+     * If the given pojo is null, try only on managed fields.
+     * @param fieldName : field name.
+     * @param pojo : the pojo on which computing field value.
+     * @return the field value, null is returned if the value is managed and not already set.
+     */
+    public synchronized Object getFieldValue(String fieldName, Object pojo) {
+        Object setByContainer = null;
+        
+        if (m_fields != null) {
+            setByContainer = m_fields.get(fieldName);
+        }
+        
+        if (setByContainer == null && pojo != null) { // In the case of no given pojo, return null.
+            // If null either the value was not already set or has the null value.
+            try {
+                Field field = pojo.getClass().getDeclaredField(fieldName);
+                if (!field.isAccessible()) {
+                    field.setAccessible(true);
+                }
+                return field.get(pojo);
+            } catch (SecurityException e) {
+                m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (NoSuchFieldException e) {
+                m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (IllegalArgumentException e) {
+                m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (IllegalAccessException e) {
+                m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            }
+            return null;
+        } else {
+            return setByContainer;
+        }
+    }
+
+    /**
      * Start the instance manager.
      */
     public synchronized void start() {
         if (m_state != STOPPED) { // Instance already started
             return;
-        } 
-        
+        }
+
         for (int i = 0; i < m_handlers.length; i++) {
             m_handlers[i].addInstanceStateListener(this);
-            m_handlers[i].start();
+            try {
+                m_handlers[i].start();
+            } catch (IllegalStateException e) {
+                m_factory.getLogger().log(Logger.ERROR, e.getMessage());
+                stop();
+                throw e;
+            }
         }
-        
+
         for (int i = 0; i < m_handlers.length; i++) {
-            
             if (m_handlers[i].getState() != VALID) {
                 setState(INVALID);
                 return;
             }
+
         }
         setState(VALID);
     }
@@ -227,26 +295,27 @@
         if (m_state == STOPPED) {
             return;
         } // Instance already stopped
-        
+
         setState(INVALID);
-        
+
+        m_state = STOPPED;
+
         // Stop all the handlers
         for (int i = m_handlers.length - 1; i > -1; i--) {
             m_handlers[i].removeInstanceStateListener(this);
             m_handlers[i].stop();
         }
-        
+
         m_pojoObjects = null;
 
-        m_state = STOPPED;
-        if (m_instanceListeners != null) {
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+        if (m_listeners != null) {
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, STOPPED);
             }
         }
     }
-    
-    /** 
+
+    /**
      * Dispose the instance.
      * @see org.apache.felix.ipojo.ComponentInstance#dispose()
      */
@@ -254,100 +323,79 @@
         if (m_state > STOPPED) { // Valid or invalid
             stop();
         }
-        
+
         m_state = DISPOSED;
-        
-        if (m_instanceListeners != null) {
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
-            }
-            m_instanceListeners = null;
+
+        for (int i = 0; m_listeners != null && i < m_listeners.size(); i++) {
+            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);
         }
-        
-        m_factory.disposed(this);
-        
+        m_listeners = null;
+
         for (int i = m_handlers.length - 1; i > -1; i--) {
             m_handlers[i].dispose();
         }
-        
-        m_map.clear();
-        m_handlers = new HandlerManager[0];
-        m_fieldRegistration = new HashMap();
-        m_methodRegistration = new HashMap();
-        m_clazz = null;
-        m_inTransition = false;
-    }
-    
-    /**
-     * Kill the current instance.
-     * Only the factory of this instance can call this method.
-     */
-    protected void kill() {
-        if (m_state > STOPPED) {
-            stop();
-        }
-        if (m_instanceListeners != null) {
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
-            }
-            m_instanceListeners = null;
-        }
 
-        // Cleaning
-        m_state = DISPOSED;
-        
-        for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].dispose();
-        }
-        
-        m_map.clear();
         m_handlers = new HandlerManager[0];
+        m_factory.disposed(this);
+        m_fields.clear();
         m_fieldRegistration = new HashMap();
         m_methodRegistration = new HashMap();
         m_clazz = null;
         m_inTransition = false;
-        
     }
-    
+
     /**
-     * Set the state of the component instance.
-     * if the state changed call the stateChanged(int) method on the handlers.
-     * This method has a reentrant mechanism. If in the flow of the first call the method is called another times, 
-     * the second call is stored and executed after the first one is finished.
+     * Set the state of the component instance. if the state changed call the stateChanged(int) method on the handlers. This method has a reentrant
+     * mechanism. If in the flow of the first call the method is called another times, the second call is stored and executed after the first one is
+     * finished.
      * @param state : the new state
      */
     public synchronized void setState(int state) {
         if (m_inTransition) {
-            m_stateQueue.add(new Integer(state)); 
+            m_stateQueue.add(new Integer(state));
             return;
         }
-        
+
         if (m_state != state) {
             m_inTransition = true;
 
             if (state > m_state) {
                 // The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower
                 m_state = state;
-                for (int i = 0; i < m_handlers.length; i++) {
-                    m_handlers[i].getHandler().stateChanged(state);
+                try {
+                    for (int i = 0; i < m_handlers.length; i++) {
+                        m_handlers[i].getHandler().stateChanged(state);
+                    }
+                } catch (IllegalStateException e) {
+                    // When an illegal state exception happens, the instance manager must be stopped immediately.
+                    m_stateQueue.clear();
+                    stop();
+                    return;
                 }
             } else {
                 // The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)
                 m_state = state;
-                for (int i = m_handlers.length - 1; i > -1; i--) {
-                    m_handlers[i].getHandler().stateChanged(state);
+                try {
+                    for (int i = m_handlers.length - 1; i > -1; i--) {
+                        m_handlers[i].getHandler().stateChanged(state);
+                    }
+                } catch (IllegalStateException e) {
+                    // When an illegal state exception happens, the instance manager must be stopped immediately.
+                    m_stateQueue.clear();
+                    stop();
+                    return;
                 }
             }
-            
-            if (m_instanceListeners != null) {
-                for (int i = 0; i < m_instanceListeners.size(); i++) {
-                    ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
+
+            if (m_listeners != null) {
+                for (int i = 0; i < m_listeners.size(); i++) {
+                    ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, state);
                 }
             }
         }
-        
+
         m_inTransition = false;
-        if (! m_stateQueue.isEmpty()) {
+        if (!m_stateQueue.isEmpty()) {
             int newState = ((Integer) (m_stateQueue.remove(0))).intValue();
             setState(newState);
         }
@@ -370,18 +418,18 @@
     public boolean isStarted() {
         return m_state > STOPPED;
     }
-    
+
     /**
      * Register an instance state listener.
      * @param listener : listener to register.
      * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
-    public void addInstanceStateListener(InstanceStateListener listener) {
-        if (m_instanceListeners == null) {
-            m_instanceListeners = new ArrayList();
+    public synchronized void addInstanceStateListener(InstanceStateListener listener) {
+        if (m_listeners == null) {
+            m_listeners = new ArrayList();
         }
-        synchronized (m_instanceListeners) {
-            m_instanceListeners.add(listener);
+        synchronized (m_listeners) {
+            m_listeners.add(listener);
         }
     }
 
@@ -390,12 +438,12 @@
      * @param listener : listener to unregister.
      * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
-    public void removeInstanceStateListener(InstanceStateListener listener) {
-        if (m_instanceListeners != null) {
-            synchronized (m_instanceListeners) {
-                m_instanceListeners.remove(listener);
-                if (m_instanceListeners.size() == 0) {
-                    m_instanceListeners = null;
+    public synchronized void removeInstanceStateListener(InstanceStateListener listener) {
+        if (m_listeners != null) {
+            synchronized (m_listeners) {
+                m_listeners.remove(listener);
+                if (m_listeners.isEmpty()) {
+                    m_listeners = null;
                 }
             }
         }
@@ -424,129 +472,186 @@
     }
 
     /**
-     * Add an instance to the created instance list.
-     * @param o : the instance to add
-     */
-    private synchronized void addInstance(Object o) {
-        if (m_pojoObjects != null) {
-            Object[] newInstances = new Object[m_pojoObjects.length + 1];
-            System.arraycopy(m_pojoObjects, 0, newInstances, 0, m_pojoObjects.length);
-            newInstances[m_pojoObjects.length] = o;
-            m_pojoObjects = newInstances;
-        } else {
-            m_pojoObjects = new Object[] { o };
-        }
-    }
-
-    /**
      * Get the array of object created by the instance.
      * @return the created instance of the component instance.
      */
     public Object[] getPojoObjects() {
-        return m_pojoObjects;
+        if (m_pojoObjects == null) {
+            return null;
+        }
+        return m_pojoObjects.toArray(new Object[m_pojoObjects.size()]);
     }
 
     /**
-     * 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) {
-                idx = i;
-                break;
-            }
-        }
-
-        if (idx >= 0) {
-            if ((m_pojoObjects.length - 1) == 0) {
-                m_pojoObjects = null;
-            } else {
-                Object[] newInstances = new Object[m_pojoObjects.length - 1];
-                System.arraycopy(m_pojoObjects, 0, newInstances, 0, idx);
-                if (idx < newInstances.length) {
-                    System.arraycopy(m_pojoObjects, idx + 1, newInstances, idx, newInstances.length - idx);
-                }
-                m_pojoObjects = newInstances;
-            }
-        }
-    }
-
-    /**
-     * Create an instance of the component. This method need to be called one
-     * time only for singleton provided service
-     * 
+     * Create an instance of the component. This method need to be called one time only for singleton provided service
      * @return a new instance
      */
     public Object createPojoObject() {
-
         if (m_clazz == null) {
             load();
         }
+
         Object instance = null;
-        try {
-            // Try to find if there is a constructor with a bundle context as
-            // parameter :
+
+        if (m_factoryMethod == null) {
+            // No factory-method, we use the constructor.
             try {
-                Constructor constructor = m_clazz.getConstructor(new Class[] { InstanceManager.class, BundleContext.class });
-                constructor.setAccessible(true);
-                instance = constructor.newInstance(new Object[] { this, m_context });
+                // Try to find if there is a constructor with a bundle context as parameter :
+                try {
+                    Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class, BundleContext.class });
+                    if (! cst.isAccessible()) {
+                        cst.setAccessible(true);
+                    }
+                    Object[] args = new Object[] { this, m_context };
+                    onEntry(null, m_className,  new Object[] {m_context});
+                    instance = cst.newInstance(args);
+                    onExit(null, m_className, instance);
+                } catch (NoSuchMethodException e) {
+                    // Create an instance if no instance are already created with <init>()BundleContext
+                    if (instance == null) {
+                        Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class });
+                        if (! cst.isAccessible()) {
+                            cst.setAccessible(true);
+                        }
+                        Object[] args = new Object[] {this};
+                        onEntry(null, m_className, new Object[0]);
+                        instance = cst.newInstance(args);
+                        onExit(null, m_className, instance);
+                    }
+                }
+            } catch (IllegalAccessException e) {
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The POJO constructor is not accessible : " + e.getMessage());
+                stop();
+            } catch (SecurityException e) {
+                m_factory.getLogger().log(
+                                          Logger.ERROR,
+                                          "["
+                                                  + m_name
+                                                  + "] createInstance -> The Component Instance is not accessible (security reason) : "
+                                                  + e.getMessage());
+                stop();
+            } catch (InvocationTargetException e) {
+                m_factory.getLogger().log(
+                                          Logger.ERROR,
+                                          "["
+                                                  + m_name
+                                                  + "] createInstance -> Cannot invoke the constructor method (illegal target) : "
+                                                  + e.getTargetException().getMessage());
+                onError(null, m_className, e.getTargetException());
+                stop();
             } catch (NoSuchMethodException e) {
-                instance = null;
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
+                stop();
+            } catch (IllegalArgumentException e) {
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The POJO constructor invocation failed : " + e.getMessage());
+                stop();
+            } catch (InstantiationException e) {
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The POJO constructor invocation failed : " + e.getMessage());
+                stop();
+            }
+        } else {
+            try {
+                // Build the pojo object with the factory-method.
+                Method factory = null;
+                // Try with the bundle context
+                try {
+                    factory = m_clazz.getDeclaredMethod(m_factoryMethod, new Class[] { BundleContext.class });
+                    if (! factory.isAccessible()) {
+                        factory.setAccessible(true);
+                    }
+                    Object[] args = new Object[] { m_context };
+                    onEntry(null, m_className, args);
+                    instance = factory.invoke(null, new Object[] { m_context });
+                } catch (NoSuchMethodException e1) {
+                    // Try without the bundle context
+                    try {
+                        factory = m_clazz.getDeclaredMethod(m_factoryMethod, new Class[0]);
+                        if (! factory.isAccessible()) {
+                            factory.setAccessible(true);
+                        }
+                        Object[] args = new Object[0];
+                        onEntry(null, m_className, args);
+                        instance = factory.invoke(null, args);
+                    } catch (NoSuchMethodException e2) {
+                        // Error : factory-method not found
+                        m_factory.getLogger().log(
+                                                  Logger.ERROR,
+                                                  "["
+                                                          + m_name
+                                                          + "] createInstance -> Cannot invoke the factory-method (method not found) : "
+                                                          + e2.getMessage());
+                        stop();
+                    }
+                }
+
+                // Now call the setInstanceManager method.
+                Method method = instance.getClass().getDeclaredMethod("_setInstanceManager", new Class[] { InstanceManager.class });
+                if (!method.isAccessible()) {
+                    method.setAccessible(true);
+                }
+                method.invoke(instance, new Object[] { this });
+                onExit(null, m_className, instance);
+
+            } catch (SecurityException e) {
+                // Error : invocation failed
+                m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+                stop();
+            } catch (IllegalArgumentException e) {
+                // Error : arguments mismatch
+                m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+                stop();
+            } catch (IllegalAccessException e) {
+                // Error : illegal access
+                m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+                stop();
+            } catch (InvocationTargetException e) {
+                // Error : invocation failed
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The factory-method returns an exception : " + e.getTargetException());
+                onError(null, m_className, e.getTargetException());
+                stop();
+            } catch (NoSuchMethodException e) {
+                // Error : _setInstanceManager method is missing
+                m_factory.getLogger()
+                        .log(
+                             Logger.ERROR,
+                             "["
+                                     + m_name
+                                     + "] createInstance -> Cannot invoke the factory-method (the _setInstanceManager method does not exist) : "
+                                     + e.getMessage());
+                stop();
             }
 
-            // Create an instance if no instance are already created with
-            // <init>()BundleContext
-            if (instance == null) {
-                Constructor constructor = m_clazz.getConstructor(new Class[] { InstanceManager.class });
-                constructor.setAccessible(true);
-                instance = constructor.newInstance(new Object[] { this });
+        }
+
+        // Register the new instance in not already present.
+        if (m_pojoObjects == null) {
+            m_pojoObjects = new ArrayList(1);
+        }
+        if (!m_pojoObjects.contains(instance)) {
+            m_pojoObjects.add(instance);
+            // Call createInstance on Handlers :
+            for (int i = 0; i < m_handlers.length; i++) {
+                ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(instance);
             }
-
-        } catch (InstantiationException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance cannot be instancied : " + e.getMessage());
-            stop();
-        } catch (IllegalAccessException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance is not accessible : " + e.getMessage());
-            stop();
-        } catch (SecurityException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance is not accessible (security reason) : " + e.getMessage());
-            stop();
-        } catch (InvocationTargetException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor method (illegal target) : " + e.getTargetException().getMessage());
-            e.printStackTrace();
-            stop();
-        } catch (NoSuchMethodException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
-            stop();
-        }
-        if (instance == null) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot create the instance");
-            stop();
         }
 
-        // Register the new instance
-        addInstance(instance);
-        // Call createInstance on Handlers :
-        for (int i = 0; i < m_handlers.length; i++) {
-            ((PrimitiveHandler) m_handlers[i].getHandler()).objectCreated(instance);
-        }
         return instance;
     }
 
     /**
-     * Get the first object created by the instance.
-     * If no object created, create and return one object.
+     * Get the first object created by the instance. If no object created, create and return one object.
      * @return the instance of the component instance to use for singleton component
      */
     public synchronized Object getPojoObject() {
         if (m_pojoObjects == null) {
-            createPojoObject();
+            return createPojoObject();
         }
-        return m_pojoObjects[0];
+        return m_pojoObjects.get(0);
     }
 
     /**
@@ -561,134 +666,219 @@
     }
 
     /**
-     * Register an handler. The handler will be notified of event on each field
-     * given in the list.
-     * 
-     * @param h : the handler to register
+     * Register an handler. The handler will be notified of event on each field given in the list.
+     * @param handler : the handler to register
      * @param fields : the field metadata list
      * @param methods : the method metadata list
+     * @deprecated use register(FieldMetadata fm, FieldInterceptor fi) and register(MethodMetadata mm, MethodInterceptor mi) instead. 
      */
-    public void register(PrimitiveHandler h, FieldMetadata[] fields, MethodMetadata[] methods) {
+    public void register(PrimitiveHandler handler, 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 PrimitiveHandler[] { h });
+            register(fields[i], handler);
+        }
+        for (int i = 0; methods != null && i < methods.length; i++) {
+            register(methods[i], handler);
+        }
+
+    }
+    
+    /**
+     * Register a field interceptor.
+     * @param field : intercepted field
+     * @param interceptor : interceptor
+     */
+    public void register(FieldMetadata field, FieldInterceptor interceptor) {
+        if (m_fieldRegistration == null) {
+            m_fieldRegistration = new HashMap();
+            m_fieldRegistration.put(field.getFieldName(), new FieldInterceptor[] { interceptor });
+        } else {
+            FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(field.getFieldName());
+            if (list == null) {
+                m_fieldRegistration.put(field.getFieldName(), new FieldInterceptor[] { interceptor });
             } else {
-                PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fields[i].getFieldName());
                 for (int j = 0; j < list.length; j++) {
-                    if (list[j] == h) {
+                    if (list[j] == interceptor) {
                         return;
                     }
                 }
-                PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
+                FieldInterceptor[] newList = new FieldInterceptor[list.length + 1];
                 System.arraycopy(list, 0, newList, 0, list.length);
-                newList[list.length] = h;
-                m_fieldRegistration.put(fields[i].getFieldName(), newList);
+                newList[list.length] = interceptor;
+                m_fieldRegistration.put(field.getFieldName(), newList);
             }
         }
-        for (int i = 0; methods != null && i < methods.length; i++) {
-            if (m_methodRegistration == null) { 
-                m_methodRegistration = new HashMap();
-                m_methodRegistration.put(methods[i].getMethodIdentifier(), new PrimitiveHandler[] { h });
-            } else { 
-                PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
-                if (list == null) {
-                    m_methodRegistration.put(methods[i].getMethodIdentifier(), new PrimitiveHandler[] { h });
-                } else {
-                    for (int j = 0; j < list.length; j++) {
-                        if (list[j] == h) {
-                            return;
-                        }
+    }
+    
+    /**
+     * Register a method interceptor.
+     * @param method : intercepted method
+     * @param interceptor : interceptor
+     */
+    public void register(MethodMetadata method, MethodInterceptor interceptor) {
+        if (m_methodRegistration == null) {
+            m_methodRegistration = new HashMap();
+            m_methodRegistration.put(method.getMethodIdentifier(), new MethodInterceptor[] { interceptor });
+        } else {
+            MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(method.getMethodIdentifier());
+            if (list == null) {
+                m_methodRegistration.put(method.getMethodIdentifier(), new MethodInterceptor[] { interceptor });
+            } else {
+                for (int j = 0; j < list.length; j++) {
+                    if (list[j] == interceptor) {
+                        return;
                     }
-                    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);
                 }
+                MethodInterceptor[] newList = new MethodInterceptor[list.length + 1];
+                System.arraycopy(list, 0, newList, 0, list.length);
+                newList[list.length] = interceptor;
+                m_methodRegistration.put(method.getMethodIdentifier(), newList);
             }
         }
-        
     }
 
     /**
-     * This method is called by the manipulated class each time that a GETFIELD
-     * instruction is found. The method ask to each handler which value need to
-     * be returned.
-     * 
-     * @param fieldName : the field name on which the GETFIELD instruction is
-     * called
-     * @return the value decided by the last asked handler (throw a warning if
-     * two fields decide two different values)
+     * This method is called by the manipulated class each time that a GETFIELD instruction is found. The method ask to each handler which value need
+     * to be returned.
+     * @param pojo : the pojo object on which the field was get
+     * @param fieldName : the field name on which the GETFIELD instruction is called
+     * @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 = m_map.get(fieldName);
+    public Object onGet(Object pojo, String fieldName) {
+        Object initialValue = m_fields.get(fieldName);
         Object result = initialValue;
         // Get the list of registered handlers
-        PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
+
+        FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(fieldName);
         for (int i = 0; list != null && i < list.length; i++) {
-            Object handlerResult = list[i].getterCallback(fieldName, initialValue);
+            Object handlerResult = list[i].onGet(null, fieldName, initialValue);
             if (handlerResult == initialValue) {
                 continue; // Non-binding case (default implementation).
             } else {
                 if (result != initialValue) {
-                    if ((handlerResult != null && ! handlerResult.equals(result)) || (result != null && handlerResult == null)) {
-                        m_factory.getLogger().log(Logger.WARNING, "A conflict was detected on the injection of " + fieldName + " - return the last value from " + list[i].getInstance().getInstanceName());
+                    if ((handlerResult != null && !handlerResult.equals(result)) || (result != null && handlerResult == null)) {
+                        m_factory.getLogger().log(
+                                                  Logger.WARNING,
+                                                  "A conflict was detected on the injection of "
+                                                          + fieldName);
                     }
                 }
                 result = handlerResult;
             }
         }
-        
-        if ((result != null && ! result.equals(initialValue)) || (result == null && initialValue != null)) {
+
+        if ((result != null && !result.equals(initialValue)) || (result == null && initialValue != null)) {
             // A change occurs => notify the change
-            m_map.put(fieldName, result);
+            m_fields.put(fieldName, result);
             for (int i = 0; list != null && i < list.length; i++) {
-                list[i].setterCallback(fieldName, result);
+                list[i].onSet(null, fieldName, result);
             }
         }
-        
-        return result;        
+
+        return result;
     }
-    
+
     /**
      * Dispatch entry method event on registered handler.
+     * @param pojo : the pojo object on which method is invoked.
      * @param methodId : method id
+     * @param args : argument array
      */
-    public void entryCallback(String methodId) {
-        PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
+    public void onEntry(Object pojo, String methodId, Object[] args) {
+        if (m_methodRegistration == null) {
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Method method = getMethodById(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
-            list[i].entryCallback(methodId);
+            list[i].onEntry(pojo, method, args);
         }
     }
 
     /**
-     * Dispatch exit method event on registered handler.
-     * The given returned object is an instance of Exception if the method has launched an exception.
+     * Dispatch exit method event on registered handler. The given returned object is an instance of Exception if the method has launched an
+     * exception. If the given object is null, either the method returns void, either the method has returned null.
+     * @param pojo : the pojo object on which the method was invoked
+     * @param methodId : method id
+     * @param result : returned object.
+     */
+    public void onExit(Object pojo, String methodId, Object result) {
+        if (m_methodRegistration == null) {
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Method method = getMethodById(methodId);
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onExit(pojo, method, result);
+        }
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onFinally(pojo, method);
+        }
+    }
+
+    /**
+     * Dispatch error method event on registered handler. The given returned object is an instance of Exception if the method has thrown an exception.
      * If the given object is null, either the method returns void, either the method has returned null.
+     * @param pojo : the pojo object on which the method was invoked
      * @param methodId : method id
-     * @param e : returned object.
+     * @param error : throwable object.
      */
-    public void exitCallback(String methodId, Object e) {
-        PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
+    public void onError(Object pojo, String methodId, Throwable error) {        
+        if (m_methodRegistration == null) {
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Method method = getMethodById(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
-            list[i].exitCallback(methodId, e);
+            list[i].onError(pojo, method, error);
+        }
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onFinally(pojo, method);
         }
     }
 
     /**
-     * This method is called by the manipulated class each time that a PUTFILED
-     * instruction is found. the method send to each handler the new value.
-     * 
-     * @param fieldName : the field name on which the PUTFIELD instruction is
-     * called
+     * Get method object by id.
+     * @param methodId : method id
+     * @return : the method object or null if the method cannot be found.
+     */
+    private Method getMethodById(String methodId) {
+        Method method = (Method) m_methods.get(methodId);
+        if (method == null) {
+            Method[] mets = m_clazz.getDeclaredMethods();
+            for (int i = 0; i < mets.length; i++) {
+                // Check if the method was not already computed. If not, compute the Id and check.
+                if (!m_methods.containsValue(mets[i]) && (MethodMetadata.computeMethodId(mets[i]).equals(methodId))) {
+                    // Store the new methodId
+                    m_methods.put(methodId, mets[i]);
+                    return mets[i];
+                }
+            }
+            // If not found, it is a constructor, return null in this case.
+            if (methodId.equals(m_clazz.getName())) {
+                // Constructor.
+                return null;
+            }
+            // Cannot happen
+            m_factory.getLogger().log(Logger.ERROR, "A methodID cannot be associate with a POJO method : " + methodId);
+            return null;
+        } else {
+            return method;
+        }
+    }
+
+    /**
+     * This method is called by the manipulated class each time that a PUTFILED instruction is found. the method send to each handler the new value.
+     * @param pojo : the pojo object on which the field was set
+     * @param fieldName : the field name on which the PUTFIELD instruction is called
      * @param objectValue : the value of the field
      */
-    public void setterCallback(String fieldName, Object objectValue) {
-        Object o = m_map.get(fieldName);
-        if ((o != null && ! o.equals(objectValue)) || (o == null && objectValue != null)) {
-            m_map.put(fieldName, objectValue);
-            PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
+    public void onSet(Object pojo, String fieldName, Object objectValue) {
+        Object value = m_fields.get(fieldName);
+        if ((value != null && !value.equals(objectValue)) || (value == null && objectValue != null)) {
+            m_fields.put(fieldName, objectValue);
+            FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(fieldName);
             for (int i = 0; list != null && i < list.length; i++) {
-                list[i].setterCallback(fieldName, objectValue);
+                list[i].onSet(null, fieldName, objectValue);
             }
         }
     }
@@ -701,11 +891,11 @@
     public BundleContext getContext() {
         return m_context;
     }
-    
+
     public BundleContext getGlobalContext() {
         return ((IPojoContext) m_context).getGlobalContext();
     }
-    
+
     public ServiceContext getLocalServiceContext() {
         return ((IPojoContext) m_context).getServiceContext();
     }
@@ -748,15 +938,16 @@
     }
 
     /**
-     * State Change listener callback.
-     * This method is notified at each time a plugged handler becomes invalid.
-     * @param instance : changing instance 
+     * 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; }
-        
+        if (m_state <= STOPPED) {
+            return;
+        }
+
         // Update the component state if necessary
         if (newState == INVALID && m_state == VALID) {
             // Need to update the state to UNRESOLVED
@@ -766,36 +957,35 @@
         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; }
+                if (m_handlers[i].getState() != VALID) {
+                    return;
+                }
             }
             setState(VALID);
             return;
-        }        
+        }
     }
-    
+
     /**
-     * Get the list of registered fields.
-     * This method is invoked by the POJO itself.
+     * Get the list of registered fields. This method is invoked by the POJO itself.
      * @return the set of registered fields.
      */
     public Set getRegistredFields() {
-        if (m_fieldRegistration != null) {
-            return m_fieldRegistration.keySet();
-        } else {
+        if (m_fieldRegistration == null) {
             return null;
         }
+        return m_fieldRegistration.keySet();
     }
-    
+
     /**
-     * Get the list of registered methods.
-     * This method is invoked by the POJO itself.
+     * Get the list of registered methods. This method is invoked by the POJO itself.
      * @return the set of registered methods.
      */
     public Set getRegistredMethods() {
-        if (m_methodRegistration != null) {
-            return m_methodRegistration.keySet();
-        } else {
+        if (m_methodRegistration == null) {
             return null;
+        } else {
+            return m_methodRegistration.keySet();
         }
     }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java
new file mode 100644
index 0000000..951452f
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java
@@ -0,0 +1,69 @@
+/* 
+ * 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.lang.reflect.Method;
+
+/**
+* Method interceptor.
+* A class implementing this interface is able to be notified of method invocation.
+* The listener need to be register on the instance manager. 
+* For event are send to the listener : before the method entry, after the method returns, 
+* when an error is thrown by the method, and before the after either a returns or an error (finally) 
+* 
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public interface MethodInterceptor {
+    
+    /**
+     * This method is called when the execution enter in a method.
+     * @param pojo : pojo on which the method is called.
+     * @param method : method invoked.
+     * @param args arguments array.
+     */
+    void onEntry(Object pojo, Method method, Object[] args);
+
+    /**
+     * This method is called when the execution exit a method (before a return or a throw).
+     * If the given returned object is null, either the method is void, either it returns null.
+     * You must not modified the returned object.
+     * @param pojo : the pojo on which the method exits.
+     * @param method : exiting method.
+     * @param returnedObj : the returned object (boxed for primitive type)
+     */
+    void onExit(Object pojo, Method method, Object returnedObj);
+    
+    /**
+     * This method is called when the execution throw an exception in the given method.
+     * @param pojo : the pojo on which the method was accessed.
+     * @param method : invoked method.
+     * @param throwable : the thrown exception
+     */
+    void onError(Object pojo, Method method, Throwable throwable);
+    
+    /**
+     * This method is called when the execution of a method will terminate : 
+     * just before to throw an exception or before to return.
+     * OnError or OnExit was already called.
+     * @param pojo : the pojo on which the method was accessed.
+     * @param method : invoked method.
+     */
+    void onFinally(Object pojo, Method method);
+
+}
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
index 7e90e43..3ba91b4 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
@@ -42,6 +42,7 @@
      * @param missing : list of missing handlers.
      */
     public MissingHandlerException(List missing) {
+        super();
         m_message = "Missing handlers : ";
         for (int i = 0; i < missing.size(); i++) {
             m_message += (String) missing.get(i) + " ";
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Nullable.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Nullable.java
index 22ce37c..797d02e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Nullable.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Nullable.java
@@ -1,28 +1,28 @@
-/* 
- * 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;
-
-/**
- * A Nullable object must implement this interface.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public interface Nullable {
-    // Nothing
-}
+/* 
+ * 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;
+
+/**
+ * A Nullable object must implement this interface.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Nullable {
+    // Nothing
+}
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 45034a2..501050c 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
@@ -22,7 +22,6 @@
 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;
@@ -85,7 +84,11 @@
     public PolicyServiceContext(BundleContext global, ServiceContext local, int policy) {
         m_global = global;
         m_local = local;
-        m_policy = policy;
+        if (m_local == null) {
+            m_policy = GLOBAL;
+        } else {
+            m_policy = policy;
+        }
     }
 
     /**
@@ -137,23 +140,7 @@
             case LOCAL_AND_GLOBAL:
                 ServiceReference[] refLocal = m_local.getAllServiceReferences(clazz, filter);
                 ServiceReference[] refGlobal = m_global.getAllServiceReferences(clazz, filter);
-                if (refLocal != null && refGlobal != null) {
-                    ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
-                    int j = 0;
-                    for (int i = 0; i < refLocal.length; i++) {
-                        refs[j] = refLocal[i];
-                        j++;
-                    }
-                    for (int i = 0; i < refGlobal.length; i++) {
-                        refs[j] = refGlobal[i];
-                        j++;
-                    }
-                    return refs;
-                } else if (refLocal != null && refGlobal == null) {
-                    return refLocal;
-                } else {
-                    return refGlobal;
-                }
+                return computeServiceReferencesFromBoth(refLocal, refGlobal);
             default:
                 return null;
         }
@@ -166,7 +153,7 @@
      * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
      */
     public Object getService(ServiceReference ref) {
-        switch(m_policy) {
+        switch(m_policy) { // NOPMD No break needed as we return in each branch.
             case LOCAL:
                 // The reference comes from the local scope
                 return m_local.getService(ref);
@@ -174,8 +161,7 @@
                 // The reference comes from the global registry
                 return m_global.getService(ref);
             case LOCAL_AND_GLOBAL:
-                if (ref instanceof org.apache.felix.ipojo.composite.ServiceReferenceImpl) {
-                    // The reference comes from a composite, i.e. necessary the local composite
+                if (ref instanceof org.apache.felix.ipojo.context.ServiceReferenceImpl) {
                     return m_local.getService(ref);
                 } else {
                     return m_global.getService(ref);
@@ -192,17 +178,17 @@
      * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
      */
     public ServiceReference getServiceReference(String clazz) {
-        switch (m_policy) {
+        switch (m_policy) { // NOPMD No break needed as we return in each branch.
             case LOCAL:
                 return m_local.getServiceReference(clazz);
             case GLOBAL:
                 return m_global.getServiceReference(clazz);
             case LOCAL_AND_GLOBAL:
                 ServiceReference refLocal = m_local.getServiceReference(clazz);
-                if (refLocal != null) {
-                    return refLocal;
+                if (refLocal == null) {
+                    return m_global.getServiceReference(clazz);
                 } else {
-                    return m_global.getServiceReference(clazz); 
+                    return refLocal;
                 }
             default:
                 return null;
@@ -226,28 +212,31 @@
             case LOCAL_AND_GLOBAL:
                 ServiceReference[] refLocal = m_local.getServiceReferences(clazz, filter);
                 ServiceReference[] refGlobal = m_global.getServiceReferences(clazz, filter);
-                if (refLocal != null && refGlobal != null) {
-                    ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
-                    int j = 0;
-                    for (int i = 0; i < refLocal.length; i++) {
-                        refs[j] = refLocal[i];
-                        j++;
-                    }
-                    for (int i = 0; i < refGlobal.length; i++) {
-                        refs[j] = refGlobal[i];
-                        j++;
-                    }
-                    return refs;
-                } else if (refLocal != null && refGlobal == null) {
-                    return refLocal;
-                } else {
-                    return refGlobal;
-                }
+                return computeServiceReferencesFromBoth(refLocal, refGlobal);
             default:
                 return null;
         }
 
     }
+    
+    /**
+     * Compute the service reference array from the two given set of service references.
+     * @param refLocal : local references
+     * @param refGlobal : global references
+     * @return the set of service reference
+     */
+    private ServiceReference[] computeServiceReferencesFromBoth(ServiceReference[] refLocal, ServiceReference[] refGlobal) {
+        if (refLocal == null) {
+            return refGlobal; // If refGlobal is null, return null, else return refGlobal
+        } else if (refGlobal == null) { // refLocal != null && refGlobal == null
+            return refLocal;
+        } else { // Both refGlobal and refLocal are not null
+            ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
+            System.arraycopy(refLocal, 0, refs, 0, refLocal.length);
+            System.arraycopy(refGlobal, 0, refs, refLocal.length, refGlobal.length);
+            return refs;
+        }        
+    }
 
     /**
      * This method is not supported.
@@ -294,7 +283,7 @@
      * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
      */
     public boolean ungetService(ServiceReference reference) {
-        if (reference instanceof ServiceReferenceImpl) {
+        if (reference instanceof org.apache.felix.ipojo.context.ServiceReferenceImpl) {
             return m_local.ungetService(reference);
         } else {
             return m_global.ungetService(reference);
@@ -343,12 +332,12 @@
 
     /**
      * Get the bundle object with the given id.
-     * @param id : bundle id
+     * @param bundleId : bundle id
      * @return the bundle object
      * @see org.osgi.framework.BundleContext#getBundle(long)
      */
-    public Bundle getBundle(long id) {
-        return m_global.getBundle(id);
+    public Bundle getBundle(long bundleId) {
+        return m_global.getBundle(bundleId);
     }
 
     /**
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
index 25a9eda..8add263 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
@@ -18,6 +18,12 @@
  */
 package org.apache.felix.ipojo;
 
+import java.lang.reflect.Method;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Logger;
+
 
 
 /**
@@ -25,7 +31,7 @@
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
-public abstract class PrimitiveHandler extends Handler {
+public abstract class PrimitiveHandler extends Handler implements FieldInterceptor, MethodInterceptor {
     
     /**
      * "Primitive" Handler type (value).
@@ -37,20 +43,45 @@
      */
     private InstanceManager m_manager;
     
+    
+    /**
+     * Factory of the instance manager. 
+     */
+    private ComponentFactory m_factory;
+    
     /**
      * Attach the current handler to the given instance.
-     * @param im ! the instance on which the current handler will be attached.
+     * @param manager ! 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;
-        setLogger(m_manager.getFactory().getLogger());
+    protected final void attach(ComponentInstance manager) {
+        m_manager = (InstanceManager) manager;
+    }
+    
+    public final void setFactory(Factory factory) {
+        m_factory = (ComponentFactory) factory;
+    }
+    
+    public Logger getLogger() {
+        return m_factory.getLogger();
     }
     
     public InstanceManager getInstanceManager() {
         return m_manager;
     }
     
+    public ComponentFactory getFactory() {
+        return m_factory;
+    }
+    
+    public Element[] getMetadata() {
+        return null;
+    }
+    
+    public PojoMetadata getPojoMetadata() {
+        return m_factory.getPojoMetadata();
+    }
+    
     /**
      * Get a plugged handler of the same container.
      * This method must be call only in the start method (or after). 
@@ -65,45 +96,76 @@
     
     /**
      * This method is called when a PUTFIELD operation is detected.
+     * @param pojo : the pojo object setting the value
      * @param fieldName : the field name
      * @param value : the value passed to the field
      */
-    public void setterCallback(String fieldName, Object value) {
-        return;
+    public void onSet(Object pojo, String fieldName, Object value) {
+        // Nothing do do in the default implementation
     }
 
     /**
      * This method is called when a GETFIELD operation is detected.
+     * @param pojo : the pojo object getting the value
      * @param fieldName : the field name
      * @param value : the value passed to the field (by the previous call)
      * @return : the managed value of the field
      */
-    public Object getterCallback(String fieldName, Object value) {
+    public Object onGet(Object pojo, String fieldName, Object value) {
         return value;
     }
     
     /**
      * This method is called when the execution enter in a method.
-     * @param methodId : the method identifier
+     * @param pojo : pojo on which the method is called.
+     * @param method : method invoked.
+     * @param args arguments array.
      */
-    public void entryCallback(String methodId) { }
+    public void onEntry(Object pojo, Method method, Object[] args) { 
+        // Nothing do do in the default implementation
+    }
 
     /**
      * 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 pojo : the pojo on which the method exits.
+     * @param method : exiting method.
      * @param returnedObj : the returned object (boxed for primitive type)
      */
-    public void exitCallback(String methodId, Object returnedObj) { }
+    public void onExit(Object pojo, Method method, Object returnedObj) { 
+        // Nothing do do in the default implementation
+    }
+    
+    /**
+     * This method is called when the execution throw an exception in the given method.
+     * @param pojo : the pojo on which the method was accessed.
+     * @param method : invoked method.
+     * @param throwable : the thrown exception
+     */
+    public void onError(Object pojo, Method method, Throwable throwable) {
+        // Nothing do do in the default implementation
+    }
+    
+    /**
+     * This method is called when the execution of a method will terminate : 
+     * just before to throw an exception or before to return.
+     * OnError or OnExit was already called.
+     * @param pojo : the pojo on which the method was accessed.
+     * @param method : invoked method.
+     */
+    public void onFinally(Object pojo, Method method) {
+        // Nothing do do in the default implementation
+    }
     
     /**
      * 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) { }
+    public void onCreation(Object instance) { 
+        // Nothing do do in the default implementation
+    }
     
     
 
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/ComponentTypeDescription.java
similarity index 66%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
index 1e6c94f..feb86ba 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/ComponentTypeDescription.java
@@ -18,20 +18,21 @@
  */
 package org.apache.felix.ipojo.architecture;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Dictionary;
+import java.util.Properties;
 
 import org.apache.felix.ipojo.ComponentFactory;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 
 /**
  * Component Type description.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ComponentDescription {
+public class ComponentTypeDescription {
 
     /**
      * Provided service by the component type.
@@ -42,13 +43,6 @@
      * Configuration Properties accepted by the component type.
      */
     private PropertyDescription[] m_properties = new PropertyDescription[0];
-    
-    /**
-     * List of required properties.
-     * This list contains only property which does not have a default value.
-     */
-    private List m_requiredProperties = new ArrayList();
-
 
     /**
      * Represented factory.
@@ -59,13 +53,9 @@
      * Constructor.
      * @param factory : represented factory.
      */
-    public ComponentDescription(Factory factory) {
+    public ComponentTypeDescription(Factory factory) {
         m_factory = factory;
     }
-    
-    public List getRequiredProperties() {
-        return m_requiredProperties;
-    }
 
     /**
      * Get a printable form of the current component type description.
@@ -98,36 +88,40 @@
      * @param value : property value.
      */
     public void addProperty(String name, String value) {
-        PropertyDescription pd = new PropertyDescription(name, String.class.getName(), value);
-        addProperty(pd);
+        addProperty(name, value, false);
+    }
+    
+    /**
+     * Add a String property in the component type.
+     * @param name : property name.
+     * @param value : property value.
+     * @param immutable : the property is immutable.
+     */
+    public void addProperty(String name, String value, boolean immutable) {
+        PropertyDescription prop = new PropertyDescription(name, String.class.getName(), value);
+        addProperty(prop);
     }
 
     /**
      * Add a configuration properties to the component type.
      * @param pd : the property to add
      */
-    public void addProperty(PropertyDescription pd) {
-        String n = pd.getName();
-        if ("name".equals(n)) {
-            pd = new PropertyDescription(n, pd.getType(), null); // Instance name case.
-        }
+    public void addProperty(PropertyDescription pd) { //NOPMD remove the instance name of the 'name' property.
+        String name = pd.getName();
+        if ("name".equals(name)) {
+            pd = new PropertyDescription(name, pd.getType(), null); //NOPMD Instance name case.
+        } 
         
         // Check if the property is not already in the array
         for (int i = 0; i < m_properties.length; i++) {
             PropertyDescription desc = m_properties[i];
-            if (desc.getName().equals(n)) {
-                return;
-            }
+            if (desc.getName().equals(name)) { return; }
         }
 
         PropertyDescription[] newProps = new PropertyDescription[m_properties.length + 1];
         System.arraycopy(m_properties, 0, newProps, 0, m_properties.length);
         newProps[m_properties.length] = pd;
         m_properties = newProps;
-        
-        if (pd.getValue() == null) {
-            m_requiredProperties.add(n);
-        }
     }
 
     /**
@@ -156,6 +150,37 @@
     public String getName() {
         return m_factory.getName();
     }
+    
+    /**
+     * Compute the default service properties to publish : 
+     * factory.name, service.pid, component.providedServiceSpecification, component.properties, component.description, factory.State.
+     * @return : the dictionary of properties to publish.
+     */
+    public Dictionary getPropertiesToPublish() {
+        Properties props = new Properties();
+
+        props.put("factory.name", m_factory.getName());
+        props.put(Constants.SERVICE_PID, m_factory.getName()); // Service PID is required for the integration in the configuration admin.
+
+        props.put("component.providedServiceSpecifications", m_providedServiceSpecification);
+        props.put("component.properties", m_properties);
+        props.put("component.description", this);
+        
+        // add every immutable property
+        for (int i = 0; i < m_properties.length; i++) {
+            if (m_properties[i].isImmutable() && m_properties[i].getValue() != null) {
+                props.put(m_properties[i].getName(), m_properties[i].getObjectValue(m_factory.getBundleContext()));
+            }
+        }
+
+        // Add factory state
+        props.put("factory.state", new Integer(m_factory.getState()));
+
+        return props;
+
+    }
+    
+    
 
     /**
      * Get the component type description.
@@ -165,14 +190,9 @@
         Element desc = new Element("Factory", "");
 
         desc.addAttribute(new Attribute("name", m_factory.getName()));
-        desc.addAttribute(new Attribute("bundle", "" + ((ComponentFactory) m_factory).getBundleContext().getBundle().getBundleId()));
-
-        String cn = getClassName();
-        if (cn == null) {
-            desc.addAttribute(new Attribute("Composite", "true"));
-        } else {
-            desc.addAttribute(new Attribute("Implementation-Class", getClassName()));
-        }
+        desc.addAttribute(
+                          new Attribute("bundle", 
+                                          Long.toString(((ComponentFactory) m_factory).getBundleContext().getBundle().getBundleId())));
 
         String state = "valid";
         if (m_factory.getState() == Factory.INVALID) {
@@ -181,12 +201,12 @@
         desc.addAttribute(new Attribute("state", state));
 
         // Display required & missing handlers
-        Element rh = new Element("RequiredHandlers", "");
-        rh.addAttribute(new Attribute("list", m_factory.getRequiredHandlers().toString()));
-        Element mh = new Element("MissingHandlers", "");
-        mh.addAttribute(new Attribute("list", m_factory.getMissingHandlers().toString()));
-        desc.addElement(rh);
-        desc.addElement(mh);
+        Element req = new Element("RequiredHandlers", "");
+        req.addAttribute(new Attribute("list", m_factory.getRequiredHandlers().toString()));
+        Element missing = new Element("MissingHandlers", "");
+        missing.addAttribute(new Attribute("list", m_factory.getMissingHandlers().toString()));
+        desc.addElement(req);
+        desc.addElement(missing);
 
         for (int i = 0; i < m_providedServiceSpecification.length; i++) {
             Element prov = new Element("provides", "");
@@ -198,10 +218,10 @@
             Element prop = new Element("property", "");
             prop.addAttribute(new Attribute("name", m_properties[i].getName()));
             prop.addAttribute(new Attribute("type", m_properties[i].getType()));
-            if (m_properties[i].getValue() != null) {
-                prop.addAttribute(new Attribute("value", m_properties[i].getValue()));
-            } else {
+            if (m_properties[i].getValue() == null) {
                 prop.addAttribute(new Attribute("value", "REQUIRED"));
+            } else {
+                prop.addAttribute(new Attribute("value", m_properties[i].getValue()));
             }
             desc.addElement(prop);
         }
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 8847575..2cd3a5a 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,7 +18,6 @@
  */
 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;
@@ -43,21 +42,11 @@
     /**
      * Constructor.
      * 
-     * @param h : handler.
+     * @param handler : handler.
      */
-    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();
+    public HandlerDescription(Handler handler) {
+        m_handlerName = handler.getClass().getName();
+        m_isValid = handler.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 14bb1e8..3ebb43a 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
@@ -57,7 +57,7 @@
     /**
      * Component Type of the instance.
      */
-    private ComponentDescription m_type;
+    private ComponentTypeDescription m_type;
 
     /**
      * COntained instance list.
@@ -70,16 +70,16 @@
      * @param name : the name of the component instance.
      * @param state : the state of the instance.
      * @param bundleId : bundle id owning this instance.
-     * @param cd : the component type description of this instance.
+     * @param desc : the component type description of this instance.
      */
-    public InstanceDescription(String name, int state, long bundleId, ComponentDescription cd) {
+    public InstanceDescription(String name, int state, long bundleId, ComponentTypeDescription desc) {
         m_name = name;
         m_state = state;
         m_createdObjects = new String[0];
         m_handlers = new HandlerDescription[0];
         m_containedInstances = new InstanceDescription[0];
         m_bundleId = bundleId;
-        m_type = cd;
+        m_type = desc;
     }
 
     /**
@@ -110,7 +110,7 @@
      * Get the component type description of the described instance.
      * @return : the component type description of this instance.
      */
-    public ComponentDescription getComponentDescription() {
+    public ComponentTypeDescription getComponentDescription() {
         return m_type;
     }
 
@@ -124,12 +124,12 @@
 
     /**
      * Add an handler description to the list.
-     * @param hd : the handler description to add
+     * @param desc : the handler description to add
      */
-    public void addHandler(HandlerDescription hd) {
+    public void addHandler(HandlerDescription desc) {
         // Verify that the dependency description is not already in the array.
         for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i] == hd) {
+            if (m_handlers[i] == desc) {
                 return; // NOTHING TO DO, the description is already in the
                         // array
             }
@@ -137,7 +137,7 @@
         // The component Description is not in the array, add it
         HandlerDescription[] newHd = new HandlerDescription[m_handlers.length + 1];
         System.arraycopy(m_handlers, 0, newHd, 0, m_handlers.length);
-        newHd[m_handlers.length] = hd;
+        newHd[m_handlers.length] = desc;
         m_handlers = newHd;
     }
 
@@ -163,10 +163,10 @@
     /**
      * Set the state of the component.
      * 
-     * @param i : the state
+     * @param state : the state
      */
-    public void setState(int i) {
-        m_state = i;
+    public void setState(int state) {
+        m_state = state;
     }
 
     /**
@@ -215,7 +215,7 @@
             instance.addAttribute(new Attribute("state", "disposed"));
         }
         // Bundle
-        instance.addAttribute(new Attribute("bundle", "" + m_bundleId));
+        instance.addAttribute(new Attribute("bundle", Long.toString(m_bundleId)));
 
         // Component Type
         instance.addAttribute(new Attribute("component.type", m_type.getName()));
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
index f3f63f4..222be42 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
@@ -18,6 +18,10 @@
  */
 package org.apache.felix.ipojo.architecture;
 
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.util.Property;
+import org.osgi.framework.BundleContext;
+
 /**
  * Property Information.
  * 
@@ -39,6 +43,14 @@
      * Default value of the property.
      */
     private String m_value = null;
+    
+    
+    /**
+     * Immutable property flag
+     * IF true, the property cannot be override by the instance configuration.
+     * Moreover, immutable properties are exposed on the factory service too.
+     */
+    private boolean m_immutable = false;
 
     /**
      * Constructor.
@@ -52,6 +64,21 @@
         m_type = type;
         m_value = value;
     }
+    
+    /**
+     * Constructor.
+     * 
+     * @param name : name of the property
+     * @param type : type of the property
+     * @param value : default value of the property
+     * @param immutable : the property is immutable.
+     */
+    public PropertyDescription(String name, String type, String value, boolean immutable) {
+        m_name = name;
+        m_type = type;
+        m_value = value;
+        m_immutable = immutable;
+    }
 
     /**
      * Get the current property name.
@@ -76,5 +103,27 @@
     public String getValue() {
         return m_value;
     }
+    
+    /**
+     * Is the property immutable.
+     * @return true if the property is immutable.
+     */
+    public boolean isImmutable() {
+        return m_immutable;
+    }
+    /**
+     * Get the object value of the current immutable property.
+     * @param context : bundle context to use to load classes.
+     * @return the object value of the current property.
+     */
+    public Object getObjectValue(BundleContext context) {
+        Class type = null;
+        try {
+            type = Property.computeType(m_type, context);
+            return Property.create(type, m_value);
+        } catch (ConfigurationException e) {
+            return m_value; // Cannot create the object.
+        }
+    }
 
 }
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
deleted file mode 100644
index d3449d6..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
+++ /dev/null
@@ -1,488 +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;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ComponentInstance;
-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.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;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * CompositeServiceContext Class. This class provides an implementation of the
- * service context for composite.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CompositeServiceContext implements ServiceContext, TrackerCustomizer {
-
-    /**
-     * Structure storing the reference, the factory and the registration.
-     */
-    private class Record {
-        /**
-         * Reference of the represented factory from the external context.
-         */
-        private ServiceReference m_ref;
-        /**
-         * Registration of the factory in the internal context.
-         */
-        private ServiceRegistration m_reg;
-        /**
-         * Represented Factory. 
-         */
-        private FactoryProxy m_fact;
-    }
-
-    /**
-     * List of imported factories.
-     */
-    private List m_factories = new ArrayList();
-
-    /**
-     * External context.
-     */
-    private BundleContext m_parent;
-
-    /**
-     * Internal service registry.
-     */
-    private ServiceRegistry m_registry;
-
-    /**
-     * Component Instance who creates this registry.
-     */
-    private ComponentInstance m_instance;
-    
-    /**
-     * 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
-     * given bundle context.
-     * 
-     * @param bc : the bundle context
-     */
-    public CompositeServiceContext(BundleContext bc) {
-        m_registry = new ServiceRegistry(bc);
-        m_parent = bc;
-        if (m_parent instanceof IPojoContext) {
-            m_global = ((IPojoContext) m_parent).getGlobalContext();
-        } else {
-            m_global = m_parent; // the parent context is the global context
-        }
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param bc : the bundle context
-     * @param ci : the component instance owning this context
-     */
-    public CompositeServiceContext(BundleContext bc, ComponentInstance ci) {
-        this(bc);
-        m_instance = ci;
-    }
-
-    /**
-     * Add a service listener.
-     * @param arg0 : The service listener to add
-     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)
-     */
-    public void addServiceListener(ServiceListener arg0) {
-        m_registry.addServiceListener(arg0);
-    }
-
-    /**
-     * Add a filtered service listener.
-     * @param arg0 : the service listener object to add
-     * @param arg1 : the LDAP filter for this listener
-     * @throws InvalidSyntaxException : occurs if the LDAP filter is malformed
-     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener,
-     * java.lang.String)
-     */
-    public void addServiceListener(ServiceListener arg0, String arg1) throws InvalidSyntaxException {
-        m_registry.addServiceListener(arg0, arg1);
-    }
-
-    /**
-     * Get all service references.
-     * @param arg0 : The required service interface.
-     * @param arg1 : LDAP filter
-     * @return the list of all service reference matching with the query
-     * @throws InvalidSyntaxException : occurs when the given filter is malformed
-     * @see org.apache.felix.ipojo.ServiceContext#getAllServiceReferences(java.lang.String,
-     * java.lang.String)
-     */
-    public ServiceReference[] getAllServiceReferences(String arg0, String arg1) throws InvalidSyntaxException {
-        return m_registry.getAllServiceReferences(arg0, arg1);
-    }
-
-    /**
-     * Get a service object for the given service reference.
-     * @param arg0 : the service reference
-     * @return the service object or null if the reference is no more valid or if the object is not accessible
-     * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
-     */
-    public Object getService(ServiceReference arg0) {
-        return m_registry.getService(m_instance, arg0);
-    }
-
-    
-    /**
-     * Get a service reference for the required interface.
-     * @param arg0 : the required interface name
-     * @return the service reference or null if no available provider
-     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
-     */
-    public ServiceReference getServiceReference(String arg0) {
-        return m_registry.getServiceReference(arg0);
-    }
-
-    /**
-     * Get all accessible service reference for the given query.
-     * @param clazz : required interface
-     * @param filter : LDAP filter
-     * @return the list (array) of service reference matching with the query.
-     * @throws InvalidSyntaxException : occurs when 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_registry.getServiceReferences(clazz, filter);
-    }
-
-
-    /**
-     * Register a service inside the composite context.
-     * @param arg0 : list of interfaces to register.
-     * @param arg1 : service object
-     * @param arg2 : properties list
-     * @return the service registration
-     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
-     */
-    public ServiceRegistration registerService(String[] arg0, Object arg1, Dictionary arg2) {
-        return m_registry.registerService(m_instance, arg0, arg1, arg2);
-    }
-
-    /**
-     * Register a service inside the composite context.
-     * @param arg0 : interface to register.
-     * @param arg1 : service object
-     * @param arg2 : properties list
-     * @return the service registration
-     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
-     */
-    public ServiceRegistration registerService(String arg0, Object arg1, Dictionary arg2) {
-        return m_registry.registerService(m_instance, arg0, arg1, arg2);
-    }
-
-    /**
-     * Remove a service listener.
-     * @param arg0 : the service listener to remove
-     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
-     */
-    public void removeServiceListener(ServiceListener arg0) {
-        m_registry.removeServiceListener(arg0);
-    }
-
-    /**
-     * Unget a service.
-     * @param arg0 the service reference to unget
-     * @return true
-     * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
-     */
-    public boolean ungetService(ServiceReference arg0) {
-        return m_registry.ungetService(m_instance, arg0);
-    }
-
-    /**
-     * Import a factory form the parent to the internal registry.
-     * 
-     * @param ref : the reference of the factory to import.
-     */
-    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_tracker.getService(ref), this);
-        rec.m_reg = registerService(Factory.class.getName(), rec.m_fact, dict);
-        rec.m_ref = ref;
-    }
-
-    /**
-     * Remove a factory of the available factory list.
-     * 
-     * @param ref : the reference on the factory to remove.
-     */
-    private void removeFactory(ServiceReference ref) {
-        for (int i = 0; i < m_factories.size(); i++) {
-            Record rec = (Record) m_factories.get(i);
-            if (rec.m_ref == 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;
-            }
-        }
-    }
-
-    /**
-     * Start the registry management.
-     */
-    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_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);
-        }
-        m_tracker = null;
-    }
-
-    /**
-     * Check if the factory list contain the given reference.
-     * 
-     * @param ref : the reference to find.
-     * @return true if the list contains the given reference.
-     */
-    private boolean containsRef(ServiceReference ref) {
-        for (int i = 0; i < m_factories.size(); i++) {
-            Record rec = (Record) m_factories.get(i);
-            if (rec.m_ref == ref) {
-                return true;
-            }
-        }
-        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)) {
-            return true;
-        }
-        return false;
-    }
-    
-    /**
-     * A matching reference has been added. The import factory can now be imported.
-     * @param reference : the added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        importFactory(reference);
-    }
-
-    /**
-     * 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
deleted file mode 100644
index 73a61e7..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
+++ /dev/null
@@ -1,177 +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;
-
-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;
-import org.osgi.framework.BundleContext;
-
-/**
- * Bridge representing a Factory inside a composition.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class FactoryProxy implements Factory {
-
-    /**
-     * Delegated factory.
-     */
-    private Factory m_delegate;
-
-    /**
-     * Destination context.
-     */
-    private ServiceContext m_context;
-
-    /**
-     * Constructor.
-     * @param fact : the targeted factory.
-     * @param s : the service context to target.
-     */
-    public FactoryProxy(Factory fact, ServiceContext s) {
-        m_delegate = fact;
-        m_context = s;
-    }
-
-    /**
-     * 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, 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 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, 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()
-     */
-    public Element getDescription() {
-        return m_delegate.getDescription();
-    }
-
-    /**
-     * Return the factory name.
-     * @return the name of the factory.
-     * @see org.apache.felix.ipojo.Factory#getName()
-     */
-    public String getName() {
-        return m_delegate.getName();
-    }
-
-    /**
-     * 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)
-     */
-    public boolean isAcceptable(Dictionary conf) {
-        return m_delegate.isAcceptable(conf);
-    }
-
-    /**
-     * 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, 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();
-    }
-
-    public String getClassName() {
-        return m_delegate.getClassName();
-    }
-
-    public int getState() {
-        return m_delegate.getState();
-    }
-
-    public BundleContext getBundleContext() {
-        return m_delegate.getBundleContext();
-    }
-
-}
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
deleted file mode 100644
index ff9ab36..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
+++ /dev/null
@@ -1,76 +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.architecture;
-
-import java.util.Dictionary;
-
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.architecture.Architecture;
-import org.apache.felix.ipojo.architecture.InstanceDescription;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * Composite Architecture Handler.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ArchitectureHandler extends CompositeHandler implements Architecture {
-
-    /**
-     * Name of the component.
-     */
-    private String m_name;
-
-    /**
-     * Configure the handler.
-     * 
-     * @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(Element metadata, Dictionary configuration) {
-        m_name = (String) configuration.get("name");
-    }
-
-    /**
-     * Stop the handler.
-     * @see org.apache.felix.ipojo.Handler#stop()
-     */
-    public void stop() { }
-
-    /**
-     * Start the handler.
-     * @see org.apache.felix.ipojo.Handler#start()
-     */
-    public void start() { 
-        log(Logger.INFO, "Start composite architecture handler with " + m_name + " name");
-    }
-
-    /**
-     * Get the instance description.
-     * @return the instance description
-     * @see org.apache.felix.ipojo.architecture.Architecture#getDescription()
-     */
-    public InstanceDescription 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
deleted file mode 100644
index b4f82b9..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
+++ /dev/null
@@ -1,406 +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.instance;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.CompositeHandler;
-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;
-
-/**
- * Composite Instance Handler.
- * This handler allows creating an instance inside a composite.
- * 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 InstanceStateListener {
-
-    /**
-     * Internal context.
-     */
-    private ServiceContext m_scope;
-
-    /**
-     * Is the handler valid ?
-     * (Lifecycle controller)
-     */
-    private boolean m_isValid = false;
-    
-    /**
-     * Available factories.
-     */
-    private Factory[] m_factories;
-    
-
-    /**
-     * This structure aims to manage a configuration. It stores all necessary
-     * information to create an instance and to track the factory.
-     */
-    class ManagedConfiguration {
-        /**
-         * Configuration of the instance to create.
-         */
-        private Dictionary m_configuration;
-
-        /**
-         * Factory name.
-         */
-        private String m_factoryName;
-
-        /**
-         * Created instance.
-         */
-        private ComponentInstance m_instance;
-        
-        /**
-         * Desired Factory (can be the classname).
-         */
-        private String m_desiredFactory;
-
-        /**
-         * Constructor.
-         * 
-         * @param conf : the configuration to create.
-         */
-        ManagedConfiguration(Dictionary conf) {
-            m_configuration = conf;
-            m_desiredFactory = (String) conf.get("component");
-        }
-
-        /**
-         * Return the managed configuration.
-         * @return the configuration.
-         */
-        Dictionary getConfiguration() {
-            return m_configuration;
-        }
-
-        /**
-         * Return the used factory name.
-         * @return the factory name
-         */
-        String getFactory() {
-            return m_factoryName;
-        }
-        
-        String getNeededFactoryName() {
-            return m_desiredFactory;
-        }
-
-        /**
-         * Return the created instance.
-         * @return the instance (or null if no instance are created).
-         */
-        ComponentInstance getInstance() {
-            return m_instance;
-        }
-
-        /**
-         * Set the factory name.
-         * 
-         * @param name : the factory name.
-         */
-        void setFactory(String name) {
-            m_factoryName = name;
-        }
-
-        /**
-         * Set the instance object.
-         * 
-         * @param instance : the instance
-         */
-        void setInstance(ComponentInstance instance) {
-            m_instance = instance;
-        }
-    }
-
-    /**
-     * Configurations to create and maintains.
-     */
-    private ManagedConfiguration[] m_configurations = new ManagedConfiguration[0];
-
-    /**
-     * Create an instance using the given factory and the given configuration.
-     * 
-     * @param fact : the factory name to used.
-     * @param config : the configuration.
-     */
-    private void createInstance(Factory fact, ManagedConfiguration config) {
-        Dictionary conf = config.getConfiguration();
-        try {
-            config.setInstance(fact.createComponentInstance(conf, m_scope));
-            config.setFactory(fact.getName());
-            config.getInstance().addInstanceStateListener(this);
-        } catch (UnacceptableConfiguration 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);
-        }
-    }
-    
-    /**
-     * A new valid factory appears.
-     * @param f : factory.
-     */
-    public void bindFactory(Factory f) {
-        boolean implicated = false;
-        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_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_isValid) {
-            checkValidity();
-        }
-    }
-
-    /**
-     * Stop all created instances.
-     */
-    public synchronized void stop() {
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null) {
-                m_configurations[i].getInstance().removeInstanceStateListener(this);
-                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 = new ManagedConfiguration[0];
-    }
-
-    /**
-     * Configure method.
-     * @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(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++) {
-            Dictionary conf = null;
-            try {
-                conf = parseInstance(instances[i]);
-            } catch (ParseException e) {
-                log(Logger.ERROR, "An instance cannot be parsed correctly", e);
-                throw new ConfigurationException("An instance cannot be parsed correctly : " + e.getMessage());
-            }
-            m_configurations[i] = new ManagedConfiguration(conf);
-        }
-    }
-
-    /**
-     * 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.
-     */
-    private Dictionary parseInstance(Element instance) throws ParseException {
-        Dictionary dict = new Properties();
-        String name = instance.getAttribute("name");
-        if (name != null) {
-            dict.put("name", name);
-        }
-        
-        String comp = instance.getAttribute("component");
-        if (comp == null) { 
-            throw new ParseException("An instance does not have the 'component' attribute"); 
-        } else {
-            dict.put("component", comp);
-        }
-
-        for (int i = 0; i < instance.getElements("property").length; i++) {
-            parseProperty(instance.getElements("property")[i], dict);
-        }
-
-        return dict;
-    }
-
-    /**
-     * Parse a property.
-     * @param prop : the current element to parse
-     * @param dict : the dictionary to populate
-     * @throws ParseException : occurs if the property cannot be parsed correctly
-     */
-    private void parseProperty(Element prop, Dictionary dict) throws ParseException {
-        // Check that the property has a name
-        String name = prop.getAttribute("name");
-        String value = prop.getAttribute("value");
-        if (name == null) { throw new ParseException("A property does not have the 'name' attribute"); }
-        // Final case : the property element has a 'value' attribute
-        if (value != null) {
-            dict.put(name, value);
-        } else {
-            // 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"); }
-            Dictionary dict2 = new Properties();
-            for (int i = 0; i < subProps.length; i++) {
-                parseProperty(subProps[i], dict2);
-                dict.put(prop.getAttribute("name"), dict2);
-            }
-        }
-    }
-
-    /**
-     * Start method.
-     * @see org.apache.felix.ipojo.CompositeHandler#start()
-     */
-    public void start() { 
-        for (int j = 0; j < m_factories.length; j++) {
-            String factName = m_factories[j].getName();
-            String className = m_factories[j].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]);
-                }
-            }
-        }
-        
-        checkValidity();
-    }
-
-    /**
-     * Check handler validity.
-     * The method update the m_validity field.
-     * @return the new validity.
-     */
-    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_isValid = false;
-                return false;
-            }
-        }
-        m_isValid = true;
-        return true;
-    }
-
-    /**
-     *  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:
-                break; // Should not happen
-            case ComponentInstance.VALID:
-                if (!m_isValid) {
-                    checkValidity();
-                }
-                break;
-            case ComponentInstance.INVALID:
-                if (m_isValid) {
-                    checkValidity();
-                }
-                break;
-            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) {
-        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(); 
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the handler description, i.e. the state of created instances.
-     * @return the handler description.
-     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
-     */
-    public HandlerDescription getDescription() {
-        List l = new ArrayList();
-        for (int i = 0; i < m_configurations.length; i++) {
-            l.add(m_configurations[i]);
-        }
-        return new InstanceHandlerDescription(this, l);
-    }
-
-    /**
-     * Get the list of used component type.
-     * @return the list containing the used component type
-     */
-    public List getUsedType() {
-        List result = new ArrayList();
-        for (int i = 0; i < m_configurations.length; i++) {
-            result.add(m_configurations[i].getConfiguration().get("component"));
-        }
-        return result;
-    }
-
-}
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
deleted file mode 100644
index 844e3e6..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
+++ /dev/null
@@ -1,90 +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.instance;
-
-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;
-
-/**
- * Description of the Instance Handler.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class InstanceHandlerDescription extends HandlerDescription {
-
-    /**
-     * List of managed instances.
-     */
-    private List m_instances;
-
-    /**
-     * Constructor.
-     * 
-     * @param h : handler
-     * @param insts : list of component instances
-     */
-    public InstanceHandlerDescription(CompositeHandler h, List insts) {
-        super(h);
-        m_instances = insts;
-    }
-
-    /**
-     * Build handler description.
-     * @return the handler description
-     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
-     */
-    public Element getHandlerInfo() {
-        Element instances = super.getHandlerInfo();
-        for (int i = 0; i < m_instances.size(); i++) {
-            ManagedConfiguration inst = (ManagedConfiguration) m_instances.get(i);
-            Element instance = new Element("Instance", "");
-            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"));
-            }
-            instances.addElement(instance);
-        }
-        return instances;
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
deleted file mode 100644
index 9994698..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
+++ /dev/null
@@ -1,72 +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.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 ExportDescription extends HandlerDescription {
-
-    /**
-     * List of exports.
-     */
-    private List m_exports;
-
-    /**
-     * Constructor.
-     * 
-     * @param h : composite handler
-     * @param exporters : list of managed exports
-     */
-    public ExportDescription(CompositeHandler h, List exporters) {
-        super(h);
-        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_exports.size(); i++) {
-            ServiceExporter exp = (ServiceExporter) m_exports.get(i);
-            Element expo = new Element("Exports", "");
-            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;
-
-    }
-}
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
deleted file mode 100644
index 707dac8..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java
+++ /dev/null
@@ -1,196 +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.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.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.
-     * @throws ConfigurationException : occurs when the 'specification' attribute is missing
-     * @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 {
-        // Update the component type description
-        Element[] exp = metadata.getElements("exports");
-        for (int i = 0; i < exp.length; i++) {
-            String spec = exp[i].getAttribute("specification");
-            if (spec != null) { 
-                cd.addProvidedServiceSpecification(spec);
-            } else {
-                // Malformed exports
-                throw new ConfigurationException("Malformed exports - Missing the specification attribute");
-            }
-        }
-    }
-
-    /**
-     * 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 = exp[i].getAttribute("specification");
-            String filter = "(objectClass=" + specification + ")";
-                
-            String opt = exp[i].getAttribute("optional");
-            optional =  opt != null && opt.equalsIgnoreCase("true");
-                
-            String agg = exp[i].getAttribute("aggregate");
-            aggregate = agg != null && agg.equalsIgnoreCase("true");
-
-            String f = exp[i].getAttribute("filter");
-            if (f != null) {
-                filter = "(&" + filter + f + ")";
-            }
-            ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, m_scope, m_context, this);
-            m_exporters.add(si);
-        }
-    }
-
-    /**
-     * 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/ImportDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
deleted file mode 100644
index 0a56014..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
+++ /dev/null
@@ -1,79 +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.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/ImportHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
deleted file mode 100644
index b54397f..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
+++ /dev/null
@@ -1,208 +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.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");
-        
-        // Get instance filters
-        Dictionary filtersConfiguration = null;
-        if (conf.get("requires.filters") != null) {
-            filtersConfiguration = (Dictionary) conf.get("requires.filters");
-        }
-
-        for (int i = 0; i < imp.length; i++) {
-            boolean optional = false;
-            boolean aggregate = false;
-            String specification = imp[i].getAttribute("specification");
-
-            if (specification != null) {                
-                String opt = imp[i].getAttribute("optional");
-                optional = opt != null && opt.equalsIgnoreCase("true");
-
-                String agg = imp[i].getAttribute("aggregate");
-                aggregate = agg != null && agg.equalsIgnoreCase("true");
-
-                String filter = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
-                String f = imp[i].getAttribute("filter");
-                if (f != null) {
-                    filter = "(&" + filter + f + ")";
-                }
-                
-                String id = imp[i].getAttribute("id");
-                
-                int scopePolicy = -1;
-                String scope = imp[i].getAttribute("scope");
-                if (scope != null) {
-                    if (scope.equalsIgnoreCase("global")) {
-                        scopePolicy = PolicyServiceContext.GLOBAL;
-                    } else if (scope.equalsIgnoreCase("composite")) {
-                        scopePolicy = PolicyServiceContext.LOCAL;
-                    } else if (scope.equalsIgnoreCase("composite+global")) {
-                        scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
-                    }                
-                }
-                
-                // Configure instance filter if available
-                if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
-                    filter = (String) filtersConfiguration.get(id);
-                }
-                
-                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");
-            }
-        }
-    }
-
-    /**
-     * 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
deleted file mode 100644
index 52347c5..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
+++ /dev/null
@@ -1,313 +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 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.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Export an service from the scope to the parent context.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceExporter implements TrackerCustomizer {
-
-    /**
-     * Destination context.
-     */
-    private BundleContext m_destination;
-
-    /**
-     * Origin context.
-     */
-    private ServiceContext m_origin;
-
-    /**
-     * Exported specification.
-     */
-    private String m_specification;
-
-    /**
-     * LDAP filter filtering internal provider.
-     */
-    private Filter m_filter;
-
-    /**
-     * String form of the LDAP filter.
-     */
-    private String m_filterStr;
-
-    /**
-     * Should be exported several providers.
-     */
-    private boolean m_aggregate = false;
-
-    /**
-     * Is this exports optional?
-     */
-    private boolean m_optional = false;
-
-    /**
-     * Reference of the 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.
-     */
-    private class Record {
-        /**
-         * Internal Reference.
-         */
-        private ServiceReference m_ref;
-        /**
-         * External Registration.
-         */
-        private ServiceRegistration m_reg;
-        /**
-         * Exposed object.
-         */
-        private Object m_svcObject;
-    }
-
-    /**
-     * List of managed records.
-     */
-    private List/*<Record>*/m_records = new ArrayList()/* <Record> */;
-
-    /**
-     * Constructor.
-     * 
-     * @param specification : exported service specification.
-     * @param filter : LDAP filter
-     * @param multiple : is the export an aggregate export?
-     * @param optional : is the export optional?
-     * @param from : internal service context
-     * @param to : external bundle context
-     * @param exp : handler
-     */
-    public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to,
-            ExportHandler exp) {
-        this.m_destination = to;
-        this.m_origin = from;
-        this.m_handler = exp;
-        try {
-            this.m_filter = to.createFilter(filter);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-            return;
-        }
-        this.m_aggregate = multiple;
-        this.m_specification = specification;
-        this.m_optional = optional;
-    }
-
-    /**
-     * Start method.
-     * Start the provider tracking and the publication.
-     */
-    public void start() {
-        m_tracker = new Tracker(m_origin, m_filter, this);
-        m_tracker.open();
-
-        m_isValid = isSatisfied();
-    }
-
-    /**
-     * Transform service reference property in a dictionary.
-     * instance.name and factory.name are injected too.
-     * @param ref : the service reference.
-     * @return the dictionary containing all property of the given service reference.
-     */
-    private Dictionary getProps(ServiceReference ref) {
-        Properties prop = new Properties();
-        String[] keys = ref.getPropertyKeys();
-        for (int i = 0; i < keys.length; i++) {
-            prop.put(keys[i], ref.getProperty(keys[i]));
-        }
-
-        prop.put("instance.name", m_handler.getCompositeManager().getInstanceName());
-        prop.put("factory.name", m_handler.getCompositeManager().getFactory().getName());
-
-        return prop;
-    }
-
-    /**
-     * Stop an exporter.
-     * Remove the service listener
-     * Unregister all exported services.
-     */
-    public void stop() {
-        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();
-                rec.m_reg = null;
-                m_tracker.ungetService(rec.m_ref);
-                rec.m_ref = null;
-            }
-        }
-
-        m_tracker = null;
-        m_records.clear();
-
-    }
-
-    /**
-     * Check the exporter validity.
-     * @return true if optional or 'valid'
-     */
-    public boolean isSatisfied() {
-        return m_optional || m_records.size() > 0;
-    }
-
-    /**
-     * Get the list of records using the given reference.
-     * @param ref : the service reference
-     * @return the list of records using the given reference, empty if no record used this reference
-     */
-    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
-        List l = new ArrayList();
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == ref) {
-                l.add(rec);
-            }
-        }
-        return l;
-    }
-    
-    protected String getSpecification() {
-        return m_specification;
-    }
-    
-    public String getFilter() {
-        return m_filterStr;
-    }
-
-    /**
-     * 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)
-     */
-    public boolean addingService(ServiceReference reference) {
-        return true;
-    }
-    
-    /**
-     * A service has been added in the tracker. Can now thest the validity of the exporter.
-     * @param reference : the new reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(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);
-        }
-    }
-
-    /**
-     * 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)
-     */
-    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_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/importer/ServiceImporter.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
deleted file mode 100644
index 9118fd2..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
+++ /dev/null
@@ -1,392 +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 java.util.Properties;
-
-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.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Import a service form the parent to the internal service registry.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceImporter implements TrackerCustomizer {
-
-    /**
-     * Destination context.
-     */
-    private ServiceContext m_destination;
-
-    /**
-     * Context where service need to be found. 
-     */
-    private ServiceContext m_origin;
-
-    /**
-     * Imported Specification.
-     */
-    private String m_specification;
-
-    /**
-     * LDAP filter filtering external providers.
-     */
-    private Filter m_filter;
-
-    /**
-     * String form of the LDAP filter.
-     */
-    private String m_filterStr;
-
-    /**
-     * Should we importer several providers?
-     */
-    private boolean m_aggregate = false;
-
-    /**
-     * Is the import optional?
-     */
-    private boolean m_optional = false;
-
-    /**
-     * Is the importer valid?
-     */
-    private boolean m_isValid;
-    
-    /**
-     * Resolving policy.
-     */
-    private int m_policy;
-    
-    /**
-     * TRacker tracking imported service.
-     */
-    private Tracker m_tracker;
-
-    /**
-     * Reference on the handler.
-     */
-    private ImportHandler m_handler;
-
-    private class Record {
-        /**
-         * External Reference.
-         */
-        private ServiceReference m_ref;
-        /**
-         * Internal Registration.
-         */
-        private ServiceRegistration m_reg;
-        /**
-         * 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;
-        }
-    }
-
-    /**
-     * List of managed records.
-     */
-    private List/*<Record>*/m_records = new ArrayList()/* <Record> */;
-
-    /**
-     * Requirement Id.
-     */
-    private String m_id;
-
-    /**
-     * Is this requirement attached to a service-level requirement.
-     */
-    private boolean m_isServiceLevelRequirement;
-
-    /**
-     * Constructor.
-     * 
-     * @param specification : targeted specification
-     * @param filter : LDAP filter
-     * @param multiple : should the importer imports several services ?
-     * @param optional : is the import optional ?
-     * @param from : parent context
-     * @param to : internal context
-     * @param policy : resolving policy
-     * @param id : requirement id (may be null)
-     * @param in : handler
-     */
-    public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to, int policy, String id,
-            ImportHandler in) {
-        this.m_destination = to;
-        try {
-            this.m_filter = from.createFilter(filter);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-            return;
-        }
-        this.m_aggregate = multiple;
-        this.m_specification = specification;
-        this.m_optional = optional;
-        this.m_handler = in;
-        
-        if (m_id == null) {
-            m_id = m_specification;
-        } else {
-            m_id = id;
-        }
-        
-        if (policy == -1) {
-            m_policy = PolicyServiceContext.LOCAL_AND_GLOBAL;  
-        } else {
-            m_policy = policy;
-        }
-    }
-
-    /**
-     * Start method to begin the import.
-     */
-    public void start() {
-        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();
-    }
-
-    /**
-     * Get the properties for the exposed service from the given reference.
-     * 
-     * @param ref : the reference.
-     * @return the property dictionary
-     */
-    private Dictionary getProps(ServiceReference ref) {
-        Properties prop = new Properties();
-        String[] keys = ref.getPropertyKeys();
-        for (int i = 0; i < keys.length; i++) {
-            prop.put(keys[i], ref.getProperty(keys[i]));
-        }
-        return prop;
-    }
-
-    /**
-     * Stop the management of the import.
-     */
-    public void stop() {
-
-        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_tracker.ungetService(rec.m_ref);
-                rec.m_ref = null;
-            }
-        }
-        
-        m_tracker = null;
-        m_records.clear();
-
-    }
-
-    /**
-     * Check if the import is satisfied.
-     * @return true if the import is optional or at least one provider is imported
-     */
-    public boolean isSatisfied() {
-        return m_optional || m_records.size() > 0;
-    }
-
-    /**
-     * Get the record list using the given reference.
-     * 
-     * @param ref : the reference
-     * @return the list containing all record using the given reference
-     */
-    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
-        List l = new ArrayList();
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == ref) {
-                l.add(rec);
-            }
-        }
-        return l;
-    }
-
-    public String getSpecification() {
-        return m_specification;
-    }
-
-    /**
-     * Build the list of imported service provider.
-     * @return the list of all imported services.
-     */
-    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("instance.name"));
-        }
-        return l;
-
-    }
-
-    public String getFilter() {
-        return m_filterStr;
-    }
-    
-    /**
-     * Set that this dependency is a service level dependency.
-     * This forces the scoping policy to be STRICT. 
-     * @param b
-     */
-    public void setServiceLevelDependency() {
-        m_isServiceLevelRequirement = true;
-        m_policy = PolicyServiceContext.LOCAL;
-    }
-
-    public String getId() {
-        return m_id;
-    }
-    
-    public boolean isServiceLevelRequirement() {
-        return m_isServiceLevelRequirement;
-    }
-    
-    public boolean isAggregate() {
-        return m_aggregate;
-    }
-    
-    public boolean isOptional() {
-        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) {
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == reference) {
-                return false; // Already contained
-            }
-        }
-        return true;
-    }
-    
-    /**
-     * The given service reference was added inside the tracker list.
-     * Register the internal service.
-     * @param reference : added reference
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(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);
-        }
-    }
-
-    /**
-     * 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
deleted file mode 100644
index c3275b9..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
+++ /dev/null
@@ -1,89 +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.instantiator;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-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;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Description of the Service Creator Handler.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceInstantiatorDescription extends HandlerDescription {
-
-    /**
-     * List of managed service instances.
-     */
-    private List m_instances;
-
-    /**
-     * Constructor.
-     * 
-     * @param h : composite handler
-     * @param insts : list of service instance
-     */
-    public ServiceInstantiatorDescription(CompositeHandler h, List insts) {
-        super(h);
-        m_instances = insts;
-    }
-
-    /**
-     * Build service instantiator handler description.
-     * @return the handler description
-     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
-     */
-    public Element getHandlerInfo() {
-        Element services = super.getHandlerInfo();
-        for (int i = 0; i < m_instances.size(); i++) {
-            SvcInstance inst = (SvcInstance) m_instances.get(i);
-            Element service = new Element("Service", "");
-            service.addAttribute(new Attribute("Specification", inst.getSpecification()));
-            String state = "unresolved";
-            if (inst.isSatisfied()) {
-                state = "resolved";
-            }
-            service.addAttribute(new Attribute("State", state));
-            Map map = inst.getUsedReferences();
-            Set keys = map.keySet();
-            Iterator it = keys.iterator();
-            while (it.hasNext()) {
-                ServiceReference ref = (ServiceReference) it.next();
-                Object o = map.get(ref);
-                if (o != null) {
-                    Element fact = new Element("Factory", "");
-                    fact.addAttribute(new Attribute("Name", ((ComponentInstance) o).getFactory().getName()));
-                    service.addElement(fact);
-                }
-            }
-            services.addElement(service);
-        }
-        return services;
-    }
-
-}
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
deleted file mode 100644
index b0f1bac..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
+++ /dev/null
@@ -1,165 +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.instantiator;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Element;
-
-/**
- * Service Instantiator Class. This handler allows to instantiate service
- * instance inside the composition.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceInstantiatorHandler extends CompositeHandler {
-
-    /**
-     * Is the handler valid ?
-     * (Lifecycle controller)
-     */
-    private boolean m_isValid;
-
-    /**
-     * List of instances to manage.
-     */
-    private List/* <SvcInstance> */m_instances = new ArrayList();
-
-    /**
-     * 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 {
-        Element[] services = metadata.getElements("service");
-        for (int i = 0; i < services.length; i++) {
-            String spec = services[i].getAttribute("specification");
-            if (spec == null) {
-                throw new ConfigurationException("Malformed service : the specification attribute is mandatory");
-            }
-            String filter = "(&(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself
-            String f = services[i].getAttribute("filter");
-            if (f != null) {
-                filter = "(&" + filter + f + ")";
-            }
-            Properties prop = new Properties();
-            for (int k = 0; k < services[i].getElements("property").length; k++) {
-                String key = services[i].getElements("property")[k].getAttribute("name");
-                String value = services[i].getElements("property")[k].getAttribute("value");
-                prop.put(key, value);
-            }
-            String ag = services[i].getAttribute("aggregate");
-            boolean agg = ag != null && ag.equalsIgnoreCase("true");
-            
-            String op = services[i].getAttribute("optional");
-            boolean opt = op != null && op.equalsIgnoreCase("true");
-            
-            SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, filter);
-            m_instances.add(inst);
-        }
-    }
-
-    /**
-     * Start the service instantiator handler.
-     * Start all created service instance.
-     * @see org.apache.felix.ipojo.CompositeHandler#start()
-     */
-    public void start() {
-        // Init
-        for (int i = 0; i < m_instances.size(); i++) {
-            SvcInstance inst = (SvcInstance) m_instances.get(i);
-            inst.start();
-        }
-
-        m_isValid = isHandlerValid();
-    }
-
-    /**
-     * Check the handler validity.
-     * @return true if all created service instances are valid
-     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
-     */
-    private boolean isHandlerValid() {
-        for (int i = 0; i < m_instances.size(); i++) {
-            SvcInstance inst = (SvcInstance) m_instances.get(i);
-            if (!inst.isSatisfied()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Handler stop method.
-     * Stop all created service instance.
-     * @see org.apache.felix.ipojo.CompositeHandler#stop()
-     */
-    public void stop() {
-        for (int i = 0; i < m_instances.size(); i++) {
-            SvcInstance inst = (SvcInstance) m_instances.get(i);
-            inst.stop();
-        }
-        m_instances.clear();
-    }
-
-    /**
-     * An service instance becomes valid.
-     */
-    public void validate() {
-        if (!m_isValid) {
-            if (isHandlerValid()) {
-                m_isValid = true;
-            }
-        }
-    }
-
-    /**
-     * A service instance becomes invalid.
-     */
-    public void invalidate() {
-        if (m_isValid) {
-            if (!isHandlerValid()) {
-                m_isValid = false;
-            }
-        }
-    }
-
-    /**
-     * Get the service instantiator handler description.
-     * @return the description
-     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
-     */
-    public HandlerDescription getDescription() {
-        return new ServiceInstantiatorDescription(this, m_instances);
-    }
-    
-    public List getInstances() {
-        return m_instances;
-    }
-}
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
deleted file mode 100644
index a738675..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
+++ /dev/null
@@ -1,387 +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.instantiator;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-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.ServiceReference;
-
-/**
- * Manage a service instantiation. This service create component instance
- * providing the required service specification.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class SvcInstance implements TrackerCustomizer {
-
-    /**
-     * Required specification.
-     */
-    private String m_specification;
-
-    /**
-     * Configuration to push to the instance.
-     */
-    private Dictionary m_configuration;
-
-    /**
-     * Map of factory references => instance or NO_INSTANCE.
-     */
-    private Map /* ServiceReference */m_usedRef = new HashMap();
-
-    /**
-     * Does we instantiate several provider ?
-     */
-    private boolean m_isAggregate = false;
-
-    /**
-     * Is the service optional ?
-     */
-    private boolean m_isOptional = false;
-
-    /**
-     * Handler creating the service instance.
-     */
-    private ServiceInstantiatorHandler m_handler;
-
-    /**
-     * Service Context (internal scope).
-     */
-    private ServiceContext m_context;
-
-    /**
-     * True if the service instantiation is valid.
-     */
-    private boolean m_isValid = false;
-
-    /**
-     * Tracker used to track required factory.
-     */
-    private Tracker m_tracker;
-
-    /**
-     * Constructor.
-     * @param h : the handler.
-     * @param spec : required specification.
-     * @param conf : instance configuration.
-     * @param isAgg : is the service instance an aggregate service ?
-     * @param isOpt : is the service instance optional ?
-     * @param filt : LDAP filter
-     */
-    public SvcInstance(ServiceInstantiatorHandler h, String spec, Dictionary conf, boolean isAgg, boolean isOpt, String filt) {
-        m_handler = h;
-        m_context = h.getCompositeManager().getServiceContext();
-        m_specification = spec;
-        m_configuration = conf;
-        m_isAggregate = isAgg;
-        m_isOptional = isOpt;
-        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() {
-        m_tracker.open();
-        m_isValid = isSatisfied();
-    }
-
-    /**
-     * Stop the service instance.
-     */
-    public void stop() {
-        m_tracker.close();
-        
-        Set keys = m_usedRef.keySet();
-        Iterator it = keys.iterator();
-        while (it.hasNext()) {
-            ServiceReference ref = (ServiceReference) it.next();
-            Object o = m_usedRef.get(ref);
-            if (o != null) {
-                ((ComponentInstance) o).dispose();
-            }
-        }
-        m_usedRef.clear();
-        m_tracker = null;
-        m_isValid = false;
-    }
-
-    /**
-     * Check if an instance is already created.
-     * @return true if at least one instance is created.
-     */
-    private boolean isAnInstanceCreated() {
-        Set keys = m_usedRef.keySet();
-        Iterator it = keys.iterator();
-        while (it.hasNext()) {
-            if (m_usedRef.get(it.next()) != null)  {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Create an instance for the given reference.
-     * 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 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;
-    }
-
-    /**
-     * Create an instance for the next available factory.
-     */
-    private void createNextInstance() {
-        Set keys = m_usedRef.keySet();
-        Iterator it = keys.iterator();
-        ServiceReference ref = (ServiceReference) it.next();
-        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 (UnacceptableConfiguration e) {
-            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());
-        }
-    }
-
-
-
-    /**
-     * Check if the service instance is satisfied.
-     * @return true if the service instance if satisfied.
-     */
-    public boolean isSatisfied() {
-        return m_isOptional || m_usedRef.size() > 0;
-    }
-
-    /**
-     * Does the service instance match with the given factory ?
-     * @param fact : the factory to test.
-     * @return true if the factory match, false otherwise.
-     */
-    private boolean match(Factory fact) {
-        //TODO : use the service reference instead of the factory object to avoid to get the factory.
-        // Check if the factory can provide the specification
-        Element[] provides = fact.getDescription().getElements("provides");
-        for (int i = 0; i < provides.length; i++) {
-            if (provides[i].getAttribute("specification").equals(m_specification)) {
-
-                // Check that the factory needs every properties contained in
-                // the configuration
-                Enumeration e = m_configuration.keys();
-                while (e.hasMoreElements()) {
-                    String k = (String) e.nextElement();
-                    if (!containsProperty(k, fact)) {
-                        return false;
-                    }
-                }
-
-                // Add an unique name if not specified.
-                Properties p = new Properties();
-                Enumeration keys = m_configuration.keys();
-                while (keys.hasMoreElements()) {
-                    String k = (String) keys.nextElement();
-                    p.put(k, m_configuration.get(k));
-                }
-
-                // Check the acceptability.
-                return fact.isAcceptable(p);
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Does the factory support the given property ?
-     * 
-     * @param name : name of the property
-     * @param factory : factory to test
-     * @return true if the factory support this property
-     */
-    private boolean containsProperty(String name, Factory factory) {
-        Element[] props = factory.getDescription().getElements("property");
-        for (int i = 0; i < props.length; i++) {
-            if (props[i].getAttribute("name").equalsIgnoreCase(name)) {
-                return true;
-            }
-        }
-        if (name.equalsIgnoreCase("name")) {
-            return true;
-        } // Skip the name property
-        return false;
-    }
-
-    /**
-     * Get the required specification.
-     * @return the required specification.
-     */
-    public String getSpecification() {
-        return m_specification;
-    }
-    
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-    
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
-    /**
-     * Get the map of used references [reference, component instance].
-     * @return the map of used references.
-     */
-    protected Map getUsedReferences() {
-        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)) {
-            m_tracker.ungetService(reference);
-            return true;
-        } else {
-            m_tracker.ungetService(reference);
-            return false;
-        }
-        
-    }
-    
-    /**
-     * A matching service reference has been added in the tracker. 
-     * @param reference : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        Factory fact = (Factory) m_tracker.getService(reference);
-        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);
-    }
-
-    /**
-     * 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/CompositionException.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
deleted file mode 100644
index 4202643..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
+++ /dev/null
@@ -1,55 +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.provides;
-
-/**
- * Exception occurs when a composition error occurs.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CompositionException extends Exception {
-
-    /**
-     * serialVersionUID.
-     */
-    private static final long serialVersionUID = -3063353267573738105L;
-
-    /**
-     * Message.
-     */
-    private String m_message;
-
-    /**
-     * Constructor.
-     * @param message : a message.
-     */
-    public CompositionException(String message) {
-        m_message = message;
-    }
-
-    /**
-     * Get the exception message.
-     * @return the message.
-     * @see java.lang.Throwable#getMessage()
-     */
-    public String getMessage() {
-        return m_message;
-    }
-
-}
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
deleted file mode 100644
index da54207..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
+++ /dev/null
@@ -1,363 +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.provides;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.felix.ipojo.Factory;
-import org.apache.felix.ipojo.manipulation.Manipulator;
-import org.apache.felix.ipojo.metadata.Attribute;
-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;
-
-/**
- * Check and build a composition, i.e. a POJO containing the composition.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CompositionMetadata {
-
-    /**
-     * Implemented composition.
-     */
-    private SpecificationMetadata m_specification;
-
-    /**
-     * Name of the composition.
-     */
-    private String m_name;
-
-    /**
-     * Bundle Context.
-     */
-    private BundleContext m_context;
-    
-    /**
-     * Manipulation Metadata.
-     */
-    private Element m_manipulationMetadata;
-
-    /**
-     * Reference on the handler.
-     */
-    private ProvidedServiceHandler m_handler;
-
-    /**
-     * List of Mappings.
-     */
-    private List m_mappings = new ArrayList();
-
-    /**
-     * Constructor.
-     * @param bc : bundle context
-     * @param description : 'provides' element
-     * @param psh : parent handler 
-     * @param name : name of the composition.
-     */
-    public CompositionMetadata(BundleContext bc, Element description, ProvidedServiceHandler psh, String name) {
-        m_context = bc;
-        m_handler = psh;
-        // Get the composition name
-        m_name = description.getAttribute("specification") + name;
-
-        // Get implemented service specification
-        String spec = description.getAttribute("specification");
-        m_specification = new SpecificationMetadata(spec, m_context, false, false, m_handler);        
-
-        Element[] mappings = description.getElements("delegation");
-        for (int i = 0; i < mappings.length; i++) {
-            String methodName = mappings[i].getAttribute("method");
-            MethodMetadata method = m_specification.getMethodByName(methodName);
-            if (method == null) {
-                m_handler.log(Logger.ERROR, "The method " + methodName + " does not exist in the specicifation " + spec);
-                return;
-            }
-
-            if (mappings[i].getAttribute("policy").equalsIgnoreCase("All")) {
-                method.setAllPolicy();
-            }
-        }
-    }
-
-    protected BundleContext getBundleContext() {
-        return m_context;
-    }
-
-    public String getName() {
-        return m_name;
-    }
-
-    public SpecificationMetadata getSpecificationMetadata() {
-        return m_specification;
-    }
-
-    /**
-     * Build Available Mappings.
-     * @throws CompositionException : a factory is not available, the composition cannot be checked.
-     */
-    private void buildAvailableMappingList() throws CompositionException {
-        int index = 0;
-        
-        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(), "(factory.name=" + type + ")");
-                if (refs == null) {
-                    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");
-                    Class impl = m_context.getBundle().loadClass(className);
-                    SpecificationMetadata spec = new SpecificationMetadata(impl, type, m_handler);
-                    FieldMetadata field = new FieldMetadata(spec);
-                    field.setName("_field" + index);
-                    Mapping map = new Mapping(spec, field);
-                    m_mappings.add(map);
-                    index++;
-                }
-            } catch (InvalidSyntaxException e) {
-                m_handler.log(Logger.ERROR, "A LDAP filter is not valid : " + e.getMessage());
-            } catch (ClassNotFoundException e) {
-                m_handler.log(Logger.ERROR, "The implementation class of a component cannot be loaded : " + e.getMessage());
-            }
-        }
-
-        for (int i = 0; i < m_handler.getSpecifications().size(); i++) {
-            SpecificationMetadata spec = (SpecificationMetadata) m_handler.getSpecifications().get(i);
-            FieldMetadata field = new FieldMetadata(spec);
-            field.setName("_field" + index);
-            if (spec.isOptional()) {
-                field.setOptional(true);
-            }
-            if (spec.isAggregate()) {
-                field.setAggregate(true);
-            }
-            Mapping map = new Mapping(spec, field);
-            m_mappings.add(map);
-            index++;
-        }
-    }
-    
-
-    /**
-     * Build the delegation mapping.
-     * @throws CompositionException : occurs when the mapping cannot be inferred correctly
-     */
-    protected void buildMapping() throws CompositionException {
-        buildAvailableMappingList();
-
-        // Dependency closure is OK, now look for method delegation
-        Map/* <MethodMetadata, Mapping> */availableSvcMethods = new HashMap();
-        Map/* <MethodMetadata, Mapping> */availableInstMethods = new HashMap();
-
-        for (int i = 0; i < m_mappings.size(); i++) {
-            Mapping map = (Mapping) m_mappings.get(i);
-            SpecificationMetadata spec = map.getSpecification();
-            for (int j = 0; j < spec.getMethods().size(); j++) {
-                MethodMetadata method = (MethodMetadata) spec.getMethods().get(j);
-                if (spec.isInterface()) { 
-                    availableSvcMethods.put(method, map);
-                } else {
-                    availableInstMethods.put(method, map);
-                }
-            }
-        }
-
-        // For each needed method, search if available and store the mapping
-        for (int j = 0; j < m_specification.getMethods().size(); j++) {
-            MethodMetadata method = (MethodMetadata) m_specification.getMethods().get(j);
-            Set keys = availableInstMethods.keySet(); // Look first in methods contained in the glue code.
-            Iterator it = keys.iterator();
-            boolean found = false;
-            while (it.hasNext() & !found) {
-                MethodMetadata met = (MethodMetadata) it.next();
-                if (met.equals(method)) {
-                    found = true;
-                    FieldMetadata field = ((Mapping) availableInstMethods.get(met)).getField();
-                    field.setUseful(true);
-                    method.setDelegation(field);
-                }
-            }
-            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 (!found && it.hasNext()) {
-                    MethodMetadata met = (MethodMetadata) it.next();
-                    if (met.equals(method)) {
-                        found = true;
-                        FieldMetadata field = ((Mapping) availableSvcMethods.get(met)).getField();
-                        field.setUseful(true);
-                        method.setDelegation(field);
-                        // Test optional
-                        if (field.isOptional() && !method.throwsUnsupportedOperationException()) {
-                            m_handler.log(Logger.WARNING, "The method " + method.getMethod().getName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");
-                        }
-                    }
-                }
-            }
-            if (!found) {
-                throw new CompositionException("Inconsistent composition - the method " + method.getMethod() + " could not be delegated");
-            }
-        }
-    }
-
-    /**
-     * Build a service implementation.
-     * @return the byte[] of the POJO.
-     */
-    protected byte[] buildPOJO() {
-        Class clazz = null;
-        try {
-            clazz = getBundleContext().getBundle().loadClass(m_specification.getName());
-        } catch (ClassNotFoundException e1) {
-            //TODO
-            e1.printStackTrace();
-        }
-        byte[] pojo = POJOWriter.dump(clazz, m_name, getFieldList(), getMethodList());
-        Manipulator m = new Manipulator();
-        try {
-            byte[] ff = m.manipulate(pojo);
-            m_manipulationMetadata = m.getManipulationMetadata();
-            return ff;
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    /**
-     * Build service implementation metadata.
-     * @param in : name of the future instance (used to avoid cycle)
-     * @return Component Type metadata. 
-     */
-    protected Element buildMetadata(String in) {
-        Element elem = new Element("component", "");
-        Attribute className = new Attribute("className", m_name);
-        Attribute factory = new Attribute("factory", "false");
-        elem.addAttribute(className);
-        elem.addAttribute(factory);
-        
-        // Add architecture for debug
-        elem.addAttribute(new Attribute("architecture", "true"));
-
-        // Provides
-        Element provides = new Element("provides", "");
-        provides.addAttribute(new Attribute("specification", m_specification.getName()));
-        elem.addElement(provides);
-
-        // Dependencies
-        List fields = getFieldList();
-        for (int i = 0; i < fields.size(); i++) {
-            FieldMetadata field = (FieldMetadata) fields.get(i);
-            if (field.isUseful() && field.getSpecification().isInterface()) {
-                Element dep = new Element("requires", "");
-                dep.addAttribute(new Attribute("field", field.getName()));
-                dep.addAttribute(new Attribute("scope", "composite"));
-                if (field.getSpecification().isOptional()) {
-                    dep.addAttribute(new Attribute("optional", "true"));
-                }
-                dep.addAttribute(new Attribute("filter", "(!(instance.name=" + in + "))"));
-                elem.addElement(dep);
-            }
-        }
-        
-        Element properties = new Element("properties", "");
-        for (int i = 0; i < fields.size(); i++) {
-            FieldMetadata field = (FieldMetadata) fields.get(i);
-            if (field.isUseful() &&  ! field.getSpecification().isInterface()) {
-                Element prop = new Element("Property", "");
-                prop.addAttribute(new Attribute("field", field.getName()));
-                properties.addElement(prop);
-            }
-        }
-        if (properties.getElements().length != 0) {
-            elem.addElement(properties);
-        }
-
-        // Insert information to metadata
-        elem.addElement(m_manipulationMetadata);
-        
-        return elem;
-    }
-
-    /**
-     * Get the field list to use for the delegation.
-     * @return the field list.
-     */
-    public List getFieldList() {
-        List list = new ArrayList();
-        for (int i = 0; i < m_mappings.size(); i++) {
-            Mapping map = (Mapping) m_mappings.get(i);
-            list.add(map.getField());
-        }
-        return list;
-    }
-
-    /**
-     * Get the method list contained in the implemented specification.
-     * @return the List of implemented method.
-     */
-    private List getMethodList() {
-        return m_specification.getMethods();
-    }
-    
-    /**
-     * Store links between Field and pointed Specification.
-     */
-    private class Mapping {
-
-        /**
-         * Specification.
-         */
-        private SpecificationMetadata m_spec;
-
-        /**
-         * Field.
-         */
-        private FieldMetadata m_field;
-
-        /**
-         * Constructor.
-         * @param spec : specification metadata.
-         * @param field : the field.
-         */
-        public Mapping(SpecificationMetadata spec, FieldMetadata field) {
-            m_spec = spec;
-            m_field = field;
-        }
-
-        public SpecificationMetadata getSpecification() {
-            return m_spec;
-        }
-
-        public FieldMetadata getField() {
-            return m_field;
-        }
-
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
deleted file mode 100644
index 2839858..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
+++ /dev/null
@@ -1,105 +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.provides;
-
-/**
- * Field used inside a composition.
- * This class contains all information useful for the generation.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class FieldMetadata {
-
-    /**
-     * Name of the field.
-     */
-    private String m_name;
-
-    /**
-     * Is the field an array?
-     */
-    private boolean m_isAggregate = false;
-
-    /**
-     * Interface of the field.
-     */
-    private SpecificationMetadata m_specification;
-
-    /**
-     * Is the field useful in this composition.
-     */
-    private boolean m_isUseful;
-
-    /**
-     * Is the dependency for this field optional.
-     */
-    private boolean m_isOptional = false;
-
-    /**
-     * Constructor.
-     * @param specification : interface of the field.
-     */
-    public FieldMetadata(SpecificationMetadata specification) {
-        super();
-        this.m_specification = specification;
-        if (m_specification.isAggregate()) {
-            m_isAggregate = true;
-        }
-    }
-
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-
-    public void setAggregate(boolean aggregate) {
-        m_isAggregate = aggregate;
-    }
-
-    public String getName() {
-        return m_name;
-    }
-
-    public void setName(String name) {
-        this.m_name = name;
-    }
-
-    public SpecificationMetadata getSpecification() {
-        return m_specification;
-    }
-
-    public void setSpecification(SpecificationMetadata specification) {
-        this.m_specification = specification;
-    }
-
-    public boolean isUseful() {
-        return m_isUseful;
-    }
-
-    public void setUseful(boolean useful) {
-        m_isUseful = useful;
-    }
-
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
-    public void setOptional(boolean opt) {
-        m_isOptional = opt;
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
deleted file mode 100644
index 5e209ae..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
+++ /dev/null
@@ -1,127 +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.provides;
-
-import java.lang.reflect.Method;
-
-/**
- * Information on Method for the composition.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class MethodMetadata {
-
-    /**
-     * ONE POLICY.
-     */
-    public static final int ONE_POLICY = 1;
-
-    /**
-     * ALL POLICY. 
-     */
-    public static final int ALL_POLICY = 2;
-
-    /**
-     * Method Object.
-     */
-    private Method m_method;
-    
-    /**
-     * Delegation field.
-     */
-    private FieldMetadata m_delegation;
-
-    /**
-     * Delegation policy (default = ONE).
-     */
-    private int m_policy = ONE_POLICY;
-
-    /**
-     * Constructor.
-     * @param method : method object.
-     */
-    public MethodMetadata(Method method) {
-        m_method = method;
-    }
-
-    public Method getMethod() {
-        return m_method;
-    }
-
-    public void setDelegation(FieldMetadata dm) {
-        m_delegation = dm;
-    }
-
-    public FieldMetadata getDelegation() {
-        return m_delegation;
-    }
-
-    /**
-     * Check if two method metadata are equals.
-     * @param mm : the method metadata to compare with the current method metadata.
-     * @return true if the two method are equals
-     */
-    public boolean equals(MethodMetadata mm) {
-        Method met = mm.getMethod();
-        return equals(met);
-    }
-
-    /**
-     * Equals method for Method object.
-     * @param met : the method object to compare.
-     * @return true if the given method signature is equals to the current method metadata.
-     */
-    public boolean equals(Method met) {
-        if (! met.getName().equals(m_method.getName()) || met.getParameterTypes().length != m_method.getParameterTypes().length) {
-            return false;
-        }
-
-        for (int i = 0; i < m_method.getParameterTypes().length; i++) {
-            if (!m_method.getParameterTypes()[i].getName().equals(met.getParameterTypes()[i].getName())) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    public int getPolicy() {
-        return m_policy;
-    }
-
-    /**
-     * Activate the all policy for this method.
-     */
-    public void setAllPolicy() {
-        m_policy = ALL_POLICY;
-    }
-    
-    /**
-     * Check if the method can throw UnsupportedOperationException.
-     * @return true if the method has declared the UnsupportedOperationException.
-     */
-    boolean throwsUnsupportedOperationException() {
-        for (int i = 0; i < m_method.getExceptionTypes().length; i++) {
-            if (m_method.getExceptionTypes()[i].getName().equals(UnsupportedOperationException.class.getName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-}
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
deleted file mode 100644
index b8fcab7..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
+++ /dev/null
@@ -1,371 +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.provides;
-
-import java.lang.reflect.Method;
-import java.util.List;
-
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-/**
- * Create the Proxy class.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class POJOWriter implements Opcodes {
-
-    /**
-     * Create a class.
-     * @param cw : class writer
-     * @param className : class name
-     * @param spec : implemented specification
-     */
-    private static void createClass(ClassWriter cw, String className, String spec) {
-        // Create the class
-        cw.visit(V1_2, ACC_PUBLIC + ACC_SUPER, className, null, "java/lang/Object", new String[] { spec.replace('.', '/') });
-    }
-
-    /**
-     * Inject field in the current class.
-     * @param cw : class writer.
-     * @param fields : list of field to inject.
-     */
-    private static void injectFields(ClassWriter cw, List fields) {
-        // Inject fields
-        for (int i = 0; i < fields.size(); i++) {
-            FieldMetadata field = (FieldMetadata) fields.get(i);
-            if (field.isUseful()) {
-                SpecificationMetadata spec = field.getSpecification();
-                String fieldName = field.getName();
-                String desc = "";
-                if (field.isAggregate()) {
-                    desc = "[L" + spec.getName().replace('.', '/') + ";";
-                } else {
-                    desc = "L" + spec.getName().replace('.', '/') + ";";
-                }
-
-                cw.visitField(Opcodes.ACC_PRIVATE, fieldName, desc, null, null);
-            }
-        }
-    }
-
-    /**
-     * Return the proxy 'classname' for the contract 'contractname' by delegating on available service.
-     * @param clazz : Specification class
-     * @param className : The class name to create
-     * @param fields : the list of fields on which delegate
-     * @param methods : the list of method on which delegate
-     * @return byte[] : the build class
-     */
-    public static byte[] dump(Class clazz, String className, List fields, List methods) {
-        Method[] itfmethods = clazz.getMethods();
-
-        // Create the class
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-        className = className.replace('.', '/');
-        createClass(cw, className, clazz.getName());
-
-        // Inject fields inside the POJO
-        injectFields(cw, fields);
-
-        // Inject a constructor <INIT>()V
-        MethodVisitor cst = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
-        cst.visitVarInsn(ALOAD, 0);
-        cst.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
-        cst.visitInsn(RETURN);
-        cst.visitMaxs(0, 0);
-        cst.visitEnd();
-
-        for (int i = 0; i < itfmethods.length; ++i) {
-            Method method = itfmethods[i];
-
-            // Get the field for this method
-            // 1) find the MethodMetadata
-            FieldMetadata delegator = null; // field to delegate
-            MethodMetadata methodDelegator = null; // field to delegate
-            for (int j = 0; j < methods.size(); j++) {
-                MethodMetadata methodMeta = (MethodMetadata) methods.get(j);
-                if (methodMeta.equals(method)) {
-                    delegator = methodMeta.getDelegation();
-                    methodDelegator = methodMeta;
-                }
-            }
-
-            generateOneMethod(cw, className, methodDelegator, method, delegator);
-
-        }
-
-        // End process
-        cw.visitEnd();
-        return cw.toByteArray();
-    }
-
-    /**
-     * Generate on method.
-     * @param cw : class writer
-     * @param className : the current class name
-     * @param method : the method to generate
-     * @param sign : method signature to generate
-     * @param delegator : the field on which delegate
-     */
-    private static void generateOneMethod(ClassWriter cw, String className, MethodMetadata method, Method sign, FieldMetadata delegator) {
-        String desc = Type.getMethodDescriptor(sign);
-        String name = sign.getName();
-        String[] exc = new String[sign.getExceptionTypes().length];
-        for (int i = 0; i < sign.getExceptionTypes().length; i++) {
-            exc[i] = Type.getType(sign.getExceptionTypes()[i]).getInternalName();
-        }
-
-        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, name, desc, null, exc);
-
-        if (delegator.isOptional()) {
-            if (!delegator.isAggregate()) {
-                generateOptionalCase(mv, delegator, className);
-            }
-            if (delegator.isAggregate() /*&& method.getPolicy() == MethodMetadata.ONE_POLICY*/) {
-                generateOptionalAggregateCase(mv, delegator, className);
-            }
-        }
-
-        if (delegator.isAggregate()) {
-            if (method.getPolicy() == MethodMetadata.ONE_POLICY) {
-                // Aggregate and One Policy
-                mv.visitVarInsn(ALOAD, 0);
-                mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "[L" + delegator.getSpecification().getName().replace('.', '/') + ";");
-                mv.visitInsn(ICONST_0); // Take the first one
-                mv.visitInsn(AALOAD);
-
-                // Loads args
-                Type[] args = Type.getArgumentTypes(desc);
-                for (int i = 0; i < args.length; i++) {
-                    writeLoad(args[i], i + 1, mv);
-                }
-
-                // Invoke
-                mv.visitMethodInsn(INVOKEINTERFACE, delegator.getSpecification().getName().replace('.', '/'), name, desc);
-
-                // Return
-                writeReturn(Type.getReturnType(desc), mv);
-            } else { // All policy
-                if (Type.getReturnType(desc).getSort() != Type.VOID) {
-                    System.err.println("All policy cannot be used on method which does not return void");
-                }
-
-                Type[] args = Type.getArgumentTypes(desc);
-                int index = args.length + 1;
-
-                // Init
-                mv.visitInsn(ICONST_0);
-                mv.visitVarInsn(ISTORE, index);
-                Label l1b = new Label();
-                mv.visitLabel(l1b);
-                Label l2b = new Label();
-                mv.visitJumpInsn(GOTO, l2b);
-
-                // Loop
-                Label l3b = new Label();
-                mv.visitLabel(l3b);
-                mv.visitVarInsn(ALOAD, 0);
-                mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "[L" + delegator.getSpecification().getName().replace('.', '/') + ";");
-                mv.visitVarInsn(ILOAD, index);
-                mv.visitInsn(AALOAD);
-
-                // Loads args
-                for (int i = 0; i < args.length; i++) {
-                    writeLoad(args[i], i + 1, mv);
-                }
-
-                mv.visitMethodInsn(INVOKEINTERFACE, delegator.getSpecification().getName().replace('.', '/'), name, desc);
-
-                Label l4b = new Label();
-                mv.visitLabel(l4b);
-                mv.visitIincInsn(index, 1); // i++;
-
-                // Condition
-                mv.visitLabel(l2b);
-                mv.visitVarInsn(ILOAD, index);
-                mv.visitVarInsn(ALOAD, 0);
-                mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "[L" + delegator.getSpecification().getName().replace('.', '/') + ";");
-                mv.visitInsn(ARRAYLENGTH);
-                mv.visitJumpInsn(IF_ICMPLT, l3b);
-
-                Label l5b = new Label();
-                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);
-        mv.visitEnd();
-    }
-
-    /**
-     * Generate Optional Case for aggregate field.
-     * @param mv : method visitor
-     * @param delegator : Field on which delegate
-     * @param className : current class name
-     */
-    private static void generateOptionalAggregateCase(MethodVisitor mv, FieldMetadata delegator, String className) {
-        mv.visitVarInsn(ALOAD, 0);
-        mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "[L" + delegator.getSpecification().getName().replace('.', '/') + ";");
-        mv.visitInsn(ARRAYLENGTH);
-        Label l1a = new Label();
-        mv.visitJumpInsn(IFNE, l1a);
-        Label l2a = new Label();
-        mv.visitLabel(l2a);
-        mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
-        mv.visitInsn(DUP);
-        mv.visitLdcInsn("Operation not supported");
-        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "(Ljava/lang/String;)V");
-        mv.visitInsn(ATHROW);
-        mv.visitLabel(l1a);
-    }
-
-    /**
-     * Generate Optional case for non aggregate fields.
-     * 
-     * @param mv : the method visitor
-     * @param delegator : the field on which delegate.
-     * @param className : the name of the current class.
-     */
-    private static void generateOptionalCase(MethodVisitor mv, FieldMetadata delegator, String className) {
-        mv.visitVarInsn(ALOAD, 0);
-        mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "L" + delegator.getSpecification().getName().replace('.', '/') + ";");
-        mv.visitTypeInsn(INSTANCEOF, "org/apache/felix/ipojo/Nullable");
-        Label end = new Label();
-        mv.visitJumpInsn(IFEQ, end);
-        Label begin = new Label();
-        mv.visitLabel(begin);
-        mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
-        mv.visitInsn(DUP);
-        mv.visitLdcInsn("Operation not supported");
-        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "(Ljava/lang/String;)V");
-        mv.visitInsn(ATHROW);
-        mv.visitLabel(end);
-    }
-
-    /**
-     * Write a return instruction according to the given type.
-     * @param t : the type
-     * @param mv : the method visitor
-     */
-    private static void writeReturn(Type t, MethodVisitor mv) {
-        switch (t.getSort()) {
-            case Type.BOOLEAN:
-            case Type.INT:
-            case Type.BYTE:
-            case Type.CHAR:
-            case Type.SHORT:
-                // Integer or Boolean : return 0 ( false)
-                mv.visitInsn(IRETURN);
-                break;
-            case Type.LONG:
-                // mv.visitInsn(LCONST_0);
-                mv.visitInsn(LRETURN);
-                break;
-            case Type.DOUBLE:
-                // Double : return 0.0
-                // mv.visitInsn(DCONST_0);
-                mv.visitInsn(DRETURN);
-                break;
-            case Type.FLOAT:
-                // Double : return 0.0
-                // mv.visitInsn(DCONST_0);
-                mv.visitInsn(FRETURN);
-                break;
-            case Type.ARRAY:
-            case Type.OBJECT:
-                // Return always null for array and object
-                // mv.visitInsn(ACONST_NULL);
-                mv.visitInsn(ARETURN);
-                break;
-            case Type.VOID:
-                mv.visitInsn(RETURN);
-                break;
-            default:
-                System.err.println("Type not yet managed : " + t);
-                break;
-        }
-    }
-
-    /**
-     * Write a load instruction according to the given type.
-     * @param t : the type
-     * @param mv : the method visitor
-     * @param index : variable name (index)
-     */
-    private static void writeLoad(Type t, int index, MethodVisitor mv) {
-        switch (t.getSort()) {
-            case Type.BOOLEAN:
-            case Type.INT:
-            case Type.BYTE:
-            case Type.CHAR:
-            case Type.SHORT:
-                // Integer or Boolean : return 0 ( false)
-                mv.visitVarInsn(ILOAD, index);
-                break;
-            case Type.LONG:
-                // mv.visitInsn(LCONST_0);
-                mv.visitVarInsn(LLOAD, index);
-                break;
-            case Type.FLOAT:
-                // mv.visitInsn(LCONST_0);
-                mv.visitVarInsn(FLOAD, index);
-                break;
-            case Type.DOUBLE:
-                // Double : return 0.0
-                // mv.visitInsn(DCONST_0);
-                mv.visitVarInsn(DLOAD, index);
-                break;
-            case Type.ARRAY:
-            case Type.OBJECT:
-                // Return always null for array and object
-                // mv.visitInsn(ACONST_NULL);
-                mv.visitVarInsn(ALOAD, index);
-                break;
-            default:
-                System.err.println("Type not yet managed : " + t);
-                break;
-        }
-    }
-
-}
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
deleted file mode 100644
index 994f01e..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
+++ /dev/null
@@ -1,234 +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.provides;
-
-import java.util.List;
-import java.util.Properties;
-
-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;
-
-/**
- * Composite Provided Service.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ProvidedService {
-
-    /**
-     * Composite Manager.
-     */
-    private CompositeManager m_manager;
-
-    /**
-     * Composition Model.
-     */
-    private CompositionMetadata m_composition;
-
-    /**
-     * generated POJO class.
-     */
-    private byte[] m_clazz;
-
-    /**
-     * Metadata of the POJO. 
-     */
-    private Element m_metadata;
-
-    /**
-     * Internal context.
-     */
-    private ServiceContext m_scope;
-
-    /**
-     * External context.
-     */
-    private BundleContext m_context;
-
-    /**
-     * Created Factory.
-     */
-    private ComponentFactory m_factory;
-
-    /**
-     * Created Instance.
-     */
-    private ComponentInstance m_instance;
-
-    /**
-     * Exporter.
-     */
-    private ServiceExporter m_exports;
-    
-    /**
-     * Created instance name.
-     */
-    private String m_instanceName;
-
-    /**
-     * Constructor.
-     * The delegation mapping is infers in this method.
-     * @param handler : the handler.
-     * @param element : 'provides' element.
-     * @param name : name of this provided service.
-     */
-    public ProvidedService(ProvidedServiceHandler handler, Element element, String name) {
-        m_manager = handler.getCompositeManager();
-        m_scope = m_manager.getServiceContext();
-        m_context = m_manager.getContext();
-        m_composition = new CompositionMetadata(m_manager.getContext(), element, handler, name);
-    }
-
-    /**
-     * Start method.
-     * Build service implementation type, factory and instance.
-     * @throws CompositionException if a consistent mapping cannot be discovered.
-     */
-    public void start() throws CompositionException {
-        m_composition.buildMapping();
-        
-        m_instanceName = m_composition.getSpecificationMetadata().getName() + "Provider-Gen";
-        m_clazz = m_composition.buildPOJO();
-        m_metadata = m_composition.buildMetadata(m_instanceName);
-
-        // Create the factory
-        m_factory = new ComponentFactory(m_context, m_clazz, m_metadata);
-        m_factory.start();
-
-        // Create the exports
-        m_exports = new ServiceExporter(m_composition.getSpecificationMetadata().getName(), "(instance.name=" + m_instanceName + ")", false, false,
-                m_scope, m_context, this);
-        m_exports.start();
-    }
-
-    /**
-     * Stop the provided service.
-     * Kill the exporter, the instance and the factory.
-     */
-    public void stop() {
-        if (m_exports != null) {
-            m_exports.stop();
-            m_exports = null;
-        }
-        if (m_instance != null) {
-            m_instance.dispose();
-            m_instance = null;
-        }
-        if (m_factory != null) {
-            m_factory.stop();
-            m_factory = null;
-        }
-    }
-
-    protected CompositeManager getManager() {
-        return m_manager;
-    }
-
-    /**
-     * The exporter becomes valid.
-     * @param exporter : the exporter
-     */
-    public void validating(ServiceExporter exporter) {
-    }
-
-    /**
-     * The exporter becomes invalid.
-     * @param exporter : the exporter
-     */
-    public void invalidating(ServiceExporter exporter) {
-    }
-
-    /**
-     * Unregister published service.
-     */
-    protected void unregister() {
-        if (m_instance != null) {
-            m_instance.dispose();
-            m_instance = null;
-        }
-    }
-
-    /**
-     * Register published service.
-     */
-    protected void register() {
-        if (m_exports != null) {
-            if (m_instance != null) { m_instance.dispose(); }
-            Properties p = new Properties();
-            p.put("name", m_instanceName);
-            List fields = m_composition.getFieldList();
-            for (int i = 0; i < fields.size(); i++) {
-                FieldMetadata fm = (FieldMetadata) fields.get(i);
-                if (fm.isUseful() && !fm.getSpecification().isInterface()) {
-                    String type = fm.getSpecification().getComponentType();
-                    Object o = getObjectByType(type);
-                    p.put(fm.getName(), o); 
-                }
-            }
-            try {
-                m_instance = m_factory.createComponentInstance(p, m_manager.getServiceContext());
-            } catch (UnacceptableConfiguration e) {
-                e.printStackTrace();
-            } catch (MissingHandlerException e) {
-                e.printStackTrace();
-            } catch (ConfigurationException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    /**
-     * Get an object from the given type.
-     * @param type : type
-     * @return an object from an instance of this type or null
-     */
-    private Object getObjectByType(String type) {
-        InstanceHandler h = (InstanceHandler) m_manager.getCompositeHandler("org.apache.felix.ipojo.composite.instance.InstanceHandler");
-        Object o = h.getObjectFromInstance(type);
-        if (o == null) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "An instance object cannot be found for the type : " + type);
-        }
-        return o;
-        
-    }
-
-    public String getSpecification() {
-        return m_composition.getSpecificationMetadata().getName();
-    }
-
-    /**
-     * Check the provided service state.
-     * @return true if the exporter is publishing.
-     */
-    public boolean getState() {
-        if (m_exports != null && m_exports.isPublishing()) {
-            return true;
-        }
-        return false;
-    }
-
-}
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
deleted file mode 100644
index ef86839..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
+++ /dev/null
@@ -1,370 +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.provides;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.CompositeHandler;
-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.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;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.parser.ManifestMetadataParser;
-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.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ProvidedServiceHandler extends CompositeHandler {
-
-    /**
-     * External context.
-     */
-    private BundleContext m_context;
-
-    /**
-     * List of "available" services in the internal context.
-     */
-    private List m_services = new ArrayList();
-
-    /**
-     * List of managed services.
-     */
-    private List m_managedServices = new ArrayList();
-
-    /**
-     * Handler validity.
-     * (Lifecycle controller)
-     */
-    private boolean m_valid = false;
-
-    /**
-     * List of component type.
-     */
-    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++) {
-            String spec = provides[i].getAttribute("specification");
-            if (spec != null) {
-                cd.addProvidedServiceSpecification(spec);
-            } else {
-                throw new ConfigurationException("Malformed provides : the specification attribute is mandatory");
-            }
-        }
-    }
-
-    /**
-     * Configure the handler.
-     * @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(Element metadata, Dictionary configuration) {
-        m_context = getCompositeManager().getContext();
-
-        // Get composition metadata
-        Element[] provides = metadata.getElements("provides", "");
-        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);
-        }
-    }
-
-    /**
-     * Start method.
-     * Start all managed provided service.
-     * @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) {
-                log(Logger.ERROR, "Cannot start the provided service handler", e);
-                if (m_valid) { m_valid = false; }
-                return;
-            }
-        }
-        m_valid = true;
-    }
-
-    /**
-     * Stop method.
-     * Stop all managed provided service.
-     * @see org.apache.felix.ipojo.CompositeHandler#stop()
-     */
-    public void stop() {
-        for (int i = 0; i < m_managedServices.size(); i++) {
-            ProvidedService ps = (ProvidedService) m_managedServices.get(i);
-            ps.stop();
-        }
-    }
-
-    /**
-     * Handler state changed.
-     * @param state : the new instance state.
-     * @see org.apache.felix.ipojo.CompositeHandler#stateChanged(int)
-     */
-    public void stateChanged(int state) {
-        if (state == ComponentInstance.INVALID) {
-            for (int i = 0; i < m_managedServices.size(); i++) {
-                ProvidedService ps = (ProvidedService) m_managedServices.get(i);
-                ps.unregister();
-            }
-            return;
-        }
-
-        // 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);
-                ps.register();
-            }
-            return;
-        }
-    }
-
-    /**
-     * Build the list of available specification.
-     * @return the list of available specification.
-     */
-    protected List getSpecifications() {
-        return m_services;
-    }
-
-    /**
-     * Build the list of available specifications.
-     */
-    private void computeAvailableServices() {
-        // Get instantiated services :
-        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);
-        }
-
-        for (int i = 0; ih != null && i < ih.getRequirements().size(); i++) {
-            ServiceImporter si = (ServiceImporter) ih.getRequirements().get(i);
-            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
-     * @throws CompositionException : occurs if the specification field of the service specification cannot be analyzed correctly.
-     */
-    private void checkServiceSpecification(ProvidedService ps) throws CompositionException {
-        try {
-            Class spec = m_context.getBundle().loadClass(ps.getSpecification());
-            Field specField = spec.getField("specification");
-            Object o = specField.get(null);
-            if (o instanceof String) {
-                Element specification = ManifestMetadataParser.parse((String) o);
-                Element[] reqs = specification.getElements("requires");
-                for (int j = 0; j < reqs.length; j++) {
-                    ServiceImporter imp = getAttachedRequirement(reqs[j]);
-                    if (imp != null) {
-                        // Fix service-level dependency flag
-                        imp.setServiceLevelDependency();
-                    }
-                    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; // No specification field
-        } catch (ClassNotFoundException e) {
-            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) {
-            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) {
-            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) {
-            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());
-        }
-    }
-
-    /**
-     * 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) {
-        ImportHandler ih = (ImportHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
-        if (ih == null) { return null; }
-
-        String id = element.getAttribute("id");
-        if (id != null) {
-            // Look for dependency 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 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; }
-        }
-        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
-     * @throws CompositionException : occurs if the requirement does not match with service-level specification requirement
-     */
-    private void checkRequirement(ServiceImporter imp, Element elem) throws CompositionException {
-        String op = elem.getAttribute("optional");
-        boolean opt = op != null && op.equalsIgnoreCase("true");
-
-        String ag = elem.getAttribute("aggregate");
-        boolean agg = ag != null && ag.equalsIgnoreCase("true");
-
-        if (imp == null) {
-            // Add the missing requirement
-            ImportHandler ih = (ImportHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
-            if (ih == null) {
-                // 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", ""), new Properties());
-                } 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 + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
-            String f = elem.getAttribute("filter");
-            if (f != null) {
-                filter = "(&" + filter + f + ")";
-            }
-            
-            ServiceImporter si = new ServiceImporter(spec, filter, agg, opt, getCompositeManager().getContext(), getCompositeManager().getServiceContext(), PolicyServiceContext.LOCAL, null, ih);
-            ih.getRequirements().add(si);
-            SpecificationMetadata sm = new SpecificationMetadata(spec, m_context, agg, opt, this);
-            m_services.add(sm); // Update the available types
-            return;
-        }
-
-        if (imp.isAggregate() && !agg) {
-            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");
-        }
-
-        String filter = elem.getAttribute("filter");
-        if (filter != null) {
-            String filter2 = imp.getFilter();
-            if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {
-                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");
-            }
-        }
-    }
-
-    public HandlerDescription getDescription() {
-        return new ProvidedServiceHandlerDescription(this, m_managedServices);
-    }
-
-    /**
-     * Build available instance types.
-     */
-    private void computeAvailableTypes() {
-        InstanceHandler ih = (InstanceHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":instance");
-        if (ih == null) {
-            m_types = new ArrayList();
-        } else {
-            m_types = ih.getUsedType();
-        }
-    }
-
-    public List getInstanceType() {
-        return m_types;
-    }
-
-}
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
deleted file mode 100644
index 19256d6..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
+++ /dev/null
@@ -1,74 +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.provides;
-
-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;
-
-/**
- * Provided Service Handler Description for composite.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ProvidedServiceHandlerDescription extends HandlerDescription {
-
-    /**
-     * Provided Service Description list.
-     */
-    private List m_providedServices = new ArrayList();
-
-    /**
-     * Constructor.
-     * 
-     * @param h : composite handler.
-     * @param ps : The list of Provided Service.
-     */
-    public ProvidedServiceHandlerDescription(CompositeHandler h, List ps) {
-        super(h);
-        m_providedServices = ps;
-    }
-
-    /**
-     * Get the handler description.
-     * @return the provided service handler description
-     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
-     */
-    public Element getHandlerInfo() {
-        Element services = super.getHandlerInfo();
-        for (int i = 0; i < m_providedServices.size(); i++) {
-            ProvidedService ps = (ProvidedService) m_providedServices.get(i);
-            Element service = new Element("service", "");
-            String state = "unregistered";
-            if (ps.getState()) {
-                state = "registered";
-            }
-            String spec = "[" + ps.getSpecification() + "]";
-            service.addAttribute(new Attribute("Specification", spec));
-            service.addAttribute(new Attribute("State", state));
-            services.addElement(service);
-        }
-        return services;
-    }
-
-}
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
deleted file mode 100644
index 080c98d..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
+++ /dev/null
@@ -1,363 +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.provides;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ServiceContext;
-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;
-
-/**
- * Export an service from the scope to the parent context.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceExporter implements ServiceListener {
-
-    /**
-     * Destination context.
-     */
-    private BundleContext m_destination;
-
-    /**
-     * Origin context.
-     */
-    private ServiceContext m_origin;
-
-    /**
-     * Exported specification.
-     */
-    private String m_specification;
-
-    /**
-     * LDAP filter filtering internal provider.
-     */
-    private Filter m_filter;
-
-    /**
-     * String form of the LDAP filter.
-     */
-    private String m_filterStr;
-
-    /**
-     * Should be exported several providers.
-     */
-    private boolean m_aggregate = false;
-
-    /**
-     * Is this exports optional?
-     */
-    private boolean m_optional = false;
-
-    /**
-     * Reference on the provided service.
-     */
-    private ProvidedService m_ps;
-
-    /**
-     * Is the export valid?
-     */
-    private boolean m_isValid;
-
-    private class Record {
-        /**
-         * Internal Reference.
-         */
-        private ServiceReference m_ref;
-        /**
-         * External Registration.
-         */
-        private ServiceRegistration m_reg;
-        /**
-         * Exposed object.
-         */
-        private Object m_svcObject;
-    }
-
-    /**
-     * List of managed records.
-     */
-    private List/* <Record> */m_records = new ArrayList()/* <Record> */;
-
-    /**
-     * Constructor.
-     * 
-     * @param specification : exported service specification.
-     * @param filter : LDAP filter
-     * @param multiple : is the export an aggregate export?
-     * @param optional : is the export optional?
-     * @param from : internal service context
-     * @param to : external bundle context
-     * @param exp : handler
-     */
-    public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to, ProvidedService exp) {
-        this.m_destination = to;
-        this.m_origin = from;
-        this.m_ps = exp;
-        try {
-            this.m_filter = to.createFilter(filter);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-            return;
-        }
-        this.m_aggregate = multiple;
-        this.m_specification = specification;
-        this.m_optional = optional;
-    }
-
-    /**
-     * Start method.
-     * Start the export and the provider tracking. 
-     */
-    public synchronized 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);
-                if (rec.m_reg == null) {
-                    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_isValid = isSatisfied();
-    }
-
-    /**
-     * Transform service reference property in a dictionary.
-     * instance.name and factory.name are injected too.
-     * @param ref : the service reference.
-     * @return the dictionary containing all property of the given service reference.
-     */
-    private Dictionary getProps(ServiceReference ref) {
-        Properties prop = new Properties();
-        String[] keys = ref.getPropertyKeys();
-        for (int i = 0; i < keys.length; i++) {
-            prop.put(keys[i], ref.getProperty(keys[i]));
-        }
-
-        prop.put("instance.name", m_ps.getManager().getInstanceName());
-        prop.put("factory.name", m_ps.getManager().getFactory().getName());
-
-        return prop;
-    }
-
-    /**
-     * Stop  method.
-     * Remove the service listener and unregister all exported service.
-     */
-    public synchronized void stop() {
-        m_origin.removeServiceListener(this);
-
-        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_ref = null;
-            }
-        }
-
-        m_records.clear();
-    }
-
-    /**
-     * Check exporter validity.
-     * @return true if the exports is optional, or a service is really exported
-     */
-    public boolean isSatisfied() {
-        return m_optional || m_records.size() > 0;
-    }
-
-    /**
-     * Check if a service is published.
-     * @return true if at least one service is published by this handler
-     */
-    public boolean isPublishing() {
-        return m_records.size() > 0;
-    }
-
-    /**
-     * Get the list of records using the given reference.
-     * @param ref : the service reference
-     * @return the list of records using the given reference, empty if no record used this reference
-     */
-    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
-        List l = new ArrayList();
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == ref) {
-                l.add(rec);
-            }
-        }
-        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 ref is always matching with the filter
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The ref 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 mathcing service => add it
-                    arrivalManagement(ev.getServiceReference());
-                }
-            } else {
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The ref is already contained => the
-                    // service does no more match
-                    departureManagement(ev.getServiceReference());
-                }
-            }
-        }
-    }
-
-    /**
-     * Manage the arrival of a service.
-     * @param ref : the new 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_ps.validating(this);
-            }
-        }
-    }
-
-    /**
-     * Manage the departure of a service.
-     * @param ref : the new service 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 reimport 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 who
-                    // 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_ps.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/provides/SpecificationMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
deleted file mode 100644
index 6ccf87b..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
+++ /dev/null
@@ -1,161 +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.provides;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.BundleContext;
-
-/**
- * Represent a service specification.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class SpecificationMetadata {
-
-    /**
-     * Name of the specification, i.e. name of the interface.
-     */
-    private String m_name;
-
-    /**
-     * List of the method contained in the specification.
-     */
-    private List/* <MethodMetadata> */m_methods = new ArrayList/* <MethodMetadata> */();
-
-    /**
-     * Is the specification an aggregate?
-     */
-    private boolean m_isAggregate;
-
-    /**
-     * Is the specification optional?
-     */
-    private boolean m_isOptional = false;
-    
-    /**
-     * Is the specification an interface?
-     */
-    private boolean m_isInterface = true;
-    
-    /**
-     * Component Type.
-     */
-    private String m_componentType = null;
-
-    /**
-     * Reference on the handler.
-     */
-    private ProvidedServiceHandler m_handler;
-
-    /**
-     * Constructor.
-     * @param name : specification name.
-     * @param bc : bundle context.
-     * @param isAggregate : is the specification aggregate.
-     * @param isOptional : is the specification optional.
-     * @param psd : the handler.
-     */
-    public SpecificationMetadata(String name, BundleContext bc, boolean isAggregate, boolean isOptional, ProvidedServiceHandler psd) {
-        m_name = name;
-        m_handler = psd;
-    
-        // Populate methods :
-        try {
-            Class clazz = bc.getBundle().loadClass(name);
-            Method[] methods = clazz.getMethods();
-            for (int i = 0; i < methods.length; i++) {
-                MethodMetadata method = new MethodMetadata(methods[i]);
-                m_methods.add(method);
-            }
-        } catch (ClassNotFoundException e) {
-            m_handler.log(Logger.ERROR, "Cannot open " + name + " : " + e.getMessage());
-            return;
-        }
-    
-        m_isAggregate = isAggregate;
-        m_isOptional = isOptional;
-    }
-
-    /**
-     * Constructor.
-     * @param c : class
-     * @param type : component type
-     * @param psd : the parent handler
-     */
-    public SpecificationMetadata(Class c, String type, ProvidedServiceHandler psd) {
-        m_handler = psd;
-        m_isAggregate = false;
-        m_isOptional = false;
-        m_componentType = type;
-        m_name = c.getName();
-        Method[] methods = c.getMethods();
-        for (int i = 0; i < methods.length; i++) {
-            MethodMetadata method = new MethodMetadata(methods[i]);    
-            m_methods.add(method);
-        }
-        m_isInterface = false;
-    }
-
-    public String getName() {
-        return m_name;
-    }
-
-    public List/* <MethodMetadata> */getMethods() {
-        return m_methods;
-    }
-
-    /**
-     * Get a method by its name.
-     * @param name : method name
-     * @return the method metadata contained in the current specification with the given name. Null if the method is not found.
-     */
-    public MethodMetadata getMethodByName(String name) {
-        for (int i = 0; i < m_methods.size(); i++) {
-            MethodMetadata met = (MethodMetadata) m_methods.get(i);
-            if (met.getMethod().getName().equals(name)) {
-                return met;
-            }
-        }
-        return null;
-    }
-
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-    
-    public boolean isInterface() {
-        return m_isInterface;
-    }
-
-    public void setIsOptional(boolean optional) {
-        m_isOptional = optional;
-    }
-    
-    public String getComponentType() {
-        return m_componentType;
-    }
-
-}
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/context/ServiceReferenceImpl.java
similarity index 86%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceReferenceImpl.java
index 1ebbcf3..7bdb382 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceReferenceImpl.java
@@ -1,112 +1,112 @@
-/* 
- * 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;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Internal service reference implementation. This class is used for in the
- * composition.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceReferenceImpl implements ServiceReference {
-
-    /**
-     * Service Registration attached to the service reference.
-     */
-    private ServiceRegistrationImpl m_registration = null;
-    
-    /**
-     * Component Instance.
-     */
-    private ComponentInstance m_cm;
-
-    /**
-     * Constructor.
-     * 
-     * @param cm : component instance publishing the service.
-     * @param sr : registration attached to this service reference.
-     */
-    public ServiceReferenceImpl(ComponentInstance cm, ServiceRegistrationImpl sr) {
-        m_registration = sr;
-        m_cm = cm;
-    }
-
-    /**
-     * Not supported in composite.
-     * @return null
-     * @see org.osgi.framework.ServiceReference#getBundle()
-     */
-    public Bundle getBundle() {
-        return m_cm.getContext().getBundle();
-    }
-
-    /**
-     * Get the service registration for this reference.
-     * @return the service registration for this service reference.
-     */
-    public ServiceRegistrationImpl getServiceRegistration() {
-        return m_registration;
-    }
-
-
-    /**
-     * Get a property value.
-     * @param s : the key of the required property.
-     * @return the property value or null if no property for the given key.
-     * @see org.osgi.framework.ServiceReference#getProperty(java.lang.String)
-     */
-    public Object getProperty(String s) {
-        return m_registration.getProperty(s);
-    }
-
-    /**
-     * Get the String arrays of service property keys.
-     * @return : the list of property keys.
-     * @see org.osgi.framework.ServiceReference#getPropertyKeys()
-     */
-    public String[] getPropertyKeys() {
-        return m_registration.getPropertyKeys();
-    }
-
-
-    /**
-     * Unsupported Operation inside composite.
-     * @return bundles using this reference.
-     * @see org.osgi.framework.ServiceReference#getUsingBundles()
-     */
-    public Bundle[] getUsingBundles() {
-        throw new UnsupportedOperationException("getUsingBundles is not supported in scope");
-    }
-
-    /**
-     * Check if the current service reference is assignable to the given bundle.
-     * @param arg0 : the bundle to check
-     * @param arg1 : the class name to check.
-     * @return true in the case of composite
-     * @see org.osgi.framework.ServiceReference#isAssignableTo(org.osgi.framework.Bundle, java.lang.String)
-     */
-    public boolean isAssignableTo(Bundle arg0, String arg1) {
-        return true;
-    }
-
-}
+/* 
+ * 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.context;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Internal service reference implementation. This class is used for in the
+ * composition.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceReferenceImpl implements ServiceReference {
+
+    /**
+     * Service Registration attached to the service reference.
+     */
+    private ServiceRegistrationImpl m_registration = null;
+    
+    /**
+     * Component Instance.
+     */
+    private ComponentInstance m_cm;
+
+    /**
+     * Constructor.
+     * 
+     * @param instance : component instance publishing the service.
+     * @param ref : registration attached to this service reference.
+     */
+    public ServiceReferenceImpl(ComponentInstance instance, ServiceRegistrationImpl ref) {
+        m_registration = ref;
+        m_cm = instance;
+    }
+
+    /**
+     * Not supported in composite.
+     * @return null
+     * @see org.osgi.framework.ServiceReference#getBundle()
+     */
+    public Bundle getBundle() {
+        return m_cm.getContext().getBundle();
+    }
+
+    /**
+     * Get the service registration for this reference.
+     * @return the service registration for this service reference.
+     */
+    public ServiceRegistrationImpl getServiceRegistration() {
+        return m_registration;
+    }
+
+
+    /**
+     * Get a property value.
+     * @param name : the key of the required property.
+     * @return the property value or null if no property for the given key.
+     * @see org.osgi.framework.ServiceReference#getProperty(java.lang.String)
+     */
+    public Object getProperty(String name) {
+        return m_registration.getProperty(name);
+    }
+
+    /**
+     * Get the String arrays of service property keys.
+     * @return : the list of property keys.
+     * @see org.osgi.framework.ServiceReference#getPropertyKeys()
+     */
+    public String[] getPropertyKeys() {
+        return m_registration.getPropertyKeys();
+    }
+
+
+    /**
+     * Unsupported Operation inside composite.
+     * @return bundles using this reference.
+     * @see org.osgi.framework.ServiceReference#getUsingBundles()
+     */
+    public Bundle[] getUsingBundles() {
+        throw new UnsupportedOperationException("getUsingBundles is not supported in scope");
+    }
+
+    /**
+     * Check if the current service reference is assignable to the given bundle.
+     * @param arg0 : the bundle to check
+     * @param arg1 : the class name to check.
+     * @return true in the case of composite
+     * @see org.osgi.framework.ServiceReference#isAssignableTo(org.osgi.framework.Bundle, java.lang.String)
+     */
+    public boolean isAssignableTo(Bundle arg0, String arg1) {
+        return true;
+    }
+
+}
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/context/ServiceRegistrationImpl.java
similarity index 87%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistrationImpl.java
index 6818899..9cd8edf 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistrationImpl.java
@@ -1,257 +1,257 @@
-/* 
- * 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;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.InstanceManager;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Internal service registration implementation. This class is used for in the
- * composition.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceRegistrationImpl implements ServiceRegistration {
-
-    /**
-     * Service Registry.
-     */
-    private ServiceRegistry m_registry = null;
-
-    /**
-     * Interfaces associated with the service object.
-     */
-    private String[] m_classes = null;
-
-    /**
-     * Service Id associated with the service object.
-     */
-    private Long m_serviceId = null;
-
-    /**
-     * Service object.
-     */
-    private Object m_svcObj = null;
-
-    /**
-     * Service factory interface.
-     */
-    private ServiceFactory m_factory = null;
-
-    /**
-     * Associated property dictionary.
-     */
-    private Map m_propMap = null;
-
-    /**
-     * Re-usable service reference.
-     */
-    private ServiceReferenceImpl m_ref = null;
-
-    /**
-     * Property Keys List.
-     */
-    private List m_list = new ArrayList();
-
-    /**
-     * Constructor.
-     * 
-     * @param registry : the service registry
-     * @param cm : component instance
-     * @param classes : published interfaces array
-     * @param serviceId : the unique service id
-     * @param svcObj : the service object or the service factory object
-     * @param dict : service properties
-     */
-    public ServiceRegistrationImpl(ServiceRegistry registry, ComponentInstance cm, String[] classes, Long serviceId, Object svcObj, Dictionary dict) {
-        m_registry = registry;
-        m_classes = classes;
-        m_serviceId = serviceId;
-        m_svcObj = svcObj;
-        if (m_svcObj instanceof ServiceFactory) { m_factory = (ServiceFactory) m_svcObj; }
-        initializeProperties(dict);
-
-        // This reference is the "standard" reference for this service and will
-        // always be returned by getReference().
-        // Since all reference to this service are supposed to be equal, we use
-        // the hash code of this reference for
-        // a references to this service in ServiceReference.
-        m_ref = new ServiceReferenceImpl(cm, this);
-    }
-
-    /**
-     * Check if the service registration still valid.
-     * @return true if the service registration is valid.
-     */
-    protected boolean isValid() {
-        return m_svcObj != null;
-    }
-
-    /**
-     * Get the service reference attached with this service registration.
-     * @return the service reference
-     * @see org.osgi.framework.ServiceRegistration#getReference()
-     */
-    public ServiceReference getReference() {
-        return m_ref;
-    }
-
-    /**
-     * Add properties to a service registration.
-     * @param dict : the properties to add
-     * @see org.osgi.framework.ServiceRegistration#setProperties(java.util.Dictionary)
-     */
-    public void setProperties(Dictionary dict) {
-        // Make sure registration is valid.
-        if (!isValid()) {
-            throw new IllegalStateException("The service registration is no longer valid.");
-        }
-        // Set the properties.
-        initializeProperties(dict);
-        // Tell registry about it.
-        m_registry.servicePropertiesModified(this);
-    }
-
-    /**
-     * Unregister the service.
-     * @see org.osgi.framework.ServiceRegistration#unregister()
-     */
-    public void unregister() {
-        if (m_svcObj != null) {
-            m_registry.unregisterService(this);
-            m_svcObj = null;
-            m_factory = null;
-        } else {
-            throw new IllegalStateException("Service already unregistered.");
-        }
-    }
-
-    /**
-     * Look for a property in the service properties.
-     * 
-     * @param key : property key
-     * @return the object associated with the key or null if the key is not
-     * present.
-     */
-    protected Object getProperty(String key) {
-        return m_propMap.get(key);
-    }
-
-    /**
-     * Get the property keys.
-     * @return the property keys list.
-     */
-    protected String[] getPropertyKeys() {
-        synchronized (m_propMap) {
-            m_list.clear();
-            Iterator i = m_propMap.entrySet().iterator();
-            while (i.hasNext()) {
-                Map.Entry entry = (Map.Entry) i.next();
-                m_list.add(entry.getKey());
-            }
-            return (String[]) m_list.toArray(new String[m_list.size()]);
-        }
-    }
-
-    /**
-     * Get the service object.
-     * @return the service object. Call the service factory if needed.
-     */
-    protected Object getService() {
-        // If the service object is a service factory, then
-        // let it create the service object.
-        if (m_factory != null) {
-            return getFactoryUnchecked();
-        } else {
-            return m_svcObj;
-        }
-    }
-
-    /**
-     * Initialize properties.
-     * 
-     * @param dict : service properties to publish.
-     */
-    private void initializeProperties(Dictionary dict) {
-        // Create a case insensitive map.
-        if (m_propMap == null) {
-            m_propMap = new StringMap(false);
-        } else {
-            m_propMap.clear();
-        }
-
-        if (dict != null) {
-            Enumeration keys = dict.keys();
-            while (keys.hasMoreElements()) {
-                Object key = keys.nextElement();
-                m_propMap.put(key, dict.get(key));
-            }
-        }
-        // Add the framework assigned properties.
-        m_propMap.put(Constants.OBJECTCLASS, m_classes);
-        m_propMap.put(Constants.SERVICE_ID, m_serviceId);
-    }
-
-    /**
-     * Get a service object via a service factory.
-     * @return the service object via the service factory invocation.
-     */
-    private Object getFactoryUnchecked() {
-        return m_factory.getService(null, this);
-    }
-
-    /**
-     * Unget a service. (Internal Method)
-     * 
-     * @param cm : component instance using the service.
-     * @param svcObj : the unget service object.
-     */
-    private void ungetFactoryUnchecked(ComponentInstance cm, Object svcObj) {
-        if (cm instanceof InstanceManager) {
-            m_factory.ungetService(((InstanceManager) cm).getContext().getBundle(), this, svcObj);
-        }
-
-    }
-
-    /**
-     * Unget a service.
-     * 
-     * @param cm : component instance using the service.
-     * @param srvObj : the unget service object.
-     */
-    public void ungetService(ComponentInstance cm, Object srvObj) {
-        // If the service object is a service factory, then let is release the
-        // service object.
-        if (m_factory != null) {
-            ungetFactoryUnchecked(cm, srvObj);
-        }
-    }
-
-}
+/* 
+ * 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.context;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.InstanceManager;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Internal service registration implementation. This class is used for in the
+ * composition.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceRegistrationImpl implements ServiceRegistration {
+
+    /**
+     * Service Registry.
+     */
+    private ServiceRegistry m_registry = null;
+
+    /**
+     * Interfaces associated with the service object.
+     */
+    private String[] m_classes = null;
+
+    /**
+     * Service Id associated with the service object.
+     */
+    private Long m_serviceId = null;
+
+    /**
+     * Service object.
+     */
+    private Object m_svcObj = null;
+
+    /**
+     * Service factory interface.
+     */
+    private ServiceFactory m_factory = null;
+
+    /**
+     * Associated property dictionary.
+     */
+    private Map m_propMap = null;
+
+    /**
+     * Re-usable service reference.
+     */
+    private ServiceReferenceImpl m_ref = null;
+
+    /**
+     * Property Keys List.
+     */
+    private List m_list = new ArrayList();
+
+    /**
+     * Constructor.
+     * 
+     * @param registry : the service registry
+     * @param instance : component instance
+     * @param classes : published interfaces array
+     * @param serviceId : the unique service id
+     * @param svcObj : the service object or the service factory object
+     * @param dict : service properties
+     */
+    public ServiceRegistrationImpl(ServiceRegistry registry, ComponentInstance instance, String[] classes, Long serviceId, Object svcObj, Dictionary dict) {
+        m_registry = registry;
+        m_classes = classes;
+        m_serviceId = serviceId;
+        m_svcObj = svcObj;
+        if (m_svcObj instanceof ServiceFactory) { m_factory = (ServiceFactory) m_svcObj; }
+        initializeProperties(dict);
+
+        // This reference is the "standard" reference for this service and will
+        // always be returned by getReference().
+        // Since all reference to this service are supposed to be equal, we use
+        // the hash code of this reference for
+        // a references to this service in ServiceReference.
+        m_ref = new ServiceReferenceImpl(instance, this);
+    }
+
+    /**
+     * Check if the service registration still valid.
+     * @return true if the service registration is valid.
+     */
+    protected boolean isValid() {
+        return m_svcObj != null;
+    }
+
+    /**
+     * Get the service reference attached with this service registration.
+     * @return the service reference
+     * @see org.osgi.framework.ServiceRegistration#getReference()
+     */
+    public ServiceReference getReference() {
+        return m_ref;
+    }
+
+    /**
+     * Add properties to a service registration.
+     * @param dict : the properties to add
+     * @see org.osgi.framework.ServiceRegistration#setProperties(java.util.Dictionary)
+     */
+    public void setProperties(Dictionary dict) {
+        // Make sure registration is valid.
+        if (!isValid()) {
+            throw new IllegalStateException("The service registration is no longer valid.");
+        }
+        // Set the properties.
+        initializeProperties(dict);
+        // Tell registry about it.
+        m_registry.servicePropertiesModified(this);
+    }
+
+    /**
+     * Unregister the service.
+     * @see org.osgi.framework.ServiceRegistration#unregister()
+     */
+    public void unregister() {
+        if (m_svcObj == null) {
+            throw new IllegalStateException("Service already unregistered.");
+        } else {
+            m_registry.unregisterService(this);
+            m_svcObj = null;
+            m_factory = null;
+        }
+    }
+
+    /**
+     * Look for a property in the service properties.
+     * 
+     * @param key : property key
+     * @return the object associated with the key or null if the key is not
+     * present.
+     */
+    protected Object getProperty(String key) {
+        return m_propMap.get(key);
+    }
+
+    /**
+     * Get the property keys.
+     * @return the property keys list.
+     */
+    protected String[] getPropertyKeys() {
+        synchronized (m_propMap) {
+            m_list.clear();
+            Iterator iterator = m_propMap.entrySet().iterator();
+            while (iterator.hasNext()) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                m_list.add(entry.getKey());
+            }
+            return (String[]) m_list.toArray(new String[m_list.size()]);
+        }
+    }
+
+    /**
+     * Get the service object.
+     * @return the service object. Call the service factory if needed.
+     */
+    protected Object getService() {
+        // If the service object is a service factory, then
+        // let it create the service object.
+        if (m_factory == null) {
+            return m_svcObj;
+        } else {
+            return getFactoryUnchecked();
+        }
+    }
+
+    /**
+     * Initialize properties.
+     * 
+     * @param dict : service properties to publish.
+     */
+    private void initializeProperties(Dictionary dict) {
+        // Create a case insensitive map.
+        if (m_propMap == null) {
+            m_propMap = new StringMap(false);
+        } else {
+            m_propMap.clear();
+        }
+
+        if (dict != null) {
+            Enumeration keys = dict.keys();
+            while (keys.hasMoreElements()) {
+                Object key = keys.nextElement();
+                m_propMap.put(key, dict.get(key));
+            }
+        }
+        // Add the framework assigned properties.
+        m_propMap.put(Constants.OBJECTCLASS, m_classes);
+        m_propMap.put(Constants.SERVICE_ID, m_serviceId);
+    }
+
+    /**
+     * Get a service object via a service factory.
+     * @return the service object via the service factory invocation.
+     */
+    private Object getFactoryUnchecked() {
+        return m_factory.getService(null, this);
+    }
+
+    /**
+     * Unget a service. (Internal Method)
+     * 
+     * @param instance : component instance using the service.
+     * @param svcObj : the unget service object.
+     */
+    private void ungetFactoryUnchecked(ComponentInstance instance, Object svcObj) {
+        if (instance instanceof InstanceManager) {
+            m_factory.ungetService(((InstanceManager) instance).getContext().getBundle(), this, svcObj);
+        }
+
+    }
+
+    /**
+     * Unget a service.
+     * 
+     * @param instance : component instance using the service.
+     * @param srvObj : the unget service object.
+     */
+    public void ungetService(ComponentInstance instance, Object srvObj) {
+        // If the service object is a service factory, then let is release the
+        // service object.
+        if (m_factory != null) {
+            ungetFactoryUnchecked(instance, srvObj);
+        }
+    }
+
+}
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/context/ServiceRegistry.java
similarity index 82%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
index c14c5e4..6eb3d7e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
@@ -1,336 +1,344 @@
-/* 
- * 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;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.felix.ipojo.ComponentInstance;
-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;
-
-/**
- * Internal Service Registry. This class is used for in the composition.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceRegistry {
-
-    /**
-     * Service Id index.
-     */
-    private long m_serviceId = 1L;
-
-    /**
-     * List of service listeners.
-     */
-    private List m_listeners = new ArrayList(); // ListenerInfo List
-
-    /**
-     * List of service registration.
-     */
-    private List m_regs = new ArrayList();
-
-    /**
-     * A "real" bundle context to create LDAP filter.
-     */
-    private BundleContext m_bc; // BundleContext to create Filter
-
-    /**
-     * Listener info structure.
-     */
-    private class ListenerInfo {
-        /**
-         * Listener object.
-         */
-        private ServiceListener m_listener;
-        /**
-         * Filter associated with the filter.
-         */
-        private Filter m_filter;
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param bc : bundle context.
-     */
-    public ServiceRegistry(BundleContext bc) {
-        m_bc = bc;
-    }
-
-    /**
-     * Add a given service listener with no filter.
-     * 
-     * @param arg0 : the service listener to add
-     */
-    public void addServiceListener(ServiceListener arg0) {
-        ListenerInfo li = new ListenerInfo();
-        li.m_listener = arg0;
-        li.m_filter = null;
-        m_listeners.add(li);
-    }
-
-    /**
-     * Unget a service.
-     * 
-     * @param cm : instance releasing the service.
-     * @param ref : released reference.
-     * @return true if the unget success
-     */
-    public boolean ungetService(ComponentInstance cm, ServiceReference ref) {
-
-        ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
-        if (reg.isValid()) {
-            reg.ungetService(cm, reg.getService());
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Unregister a service listener.
-     * 
-     * @param arg0 : the service listener to remove
-     */
-    public void removeServiceListener(ServiceListener arg0) {
-        m_listeners.remove(arg0);
-    }
-
-    /**
-     * Register a service.
-     * 
-     * @param cm : provider instance.
-     * @param clazz : provided interface.
-     * @param svcObj : service object of service factory object.
-     * @param dict : service properties.
-     * @return the created service registration.
-     */
-    public ServiceRegistration registerService(ComponentInstance cm, String clazz, Object svcObj, Dictionary dict) {
-        synchronized (m_regs) {
-            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, cm, new String[] { clazz }, new Long(m_serviceId++), svcObj, dict);
-            m_regs.add(reg);
-            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
-            return reg;
-        }
-    }
-
-    /**
-     * Register a service.
-     * 
-     * @param cm : provider instance.
-     * @param clazzes : provided interfaces.
-     * @param svcObj : service object of service factory object.
-     * @param dict : service properties.
-     * @return the created service registration.
-     */
-    public ServiceRegistration registerService(ComponentInstance cm, String[] clazzes, Object svcObj, Dictionary dict) {
-        synchronized (m_regs) {
-            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, cm, clazzes, new Long(m_serviceId++), svcObj, dict);
-            m_regs.add(reg);
-            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
-            return reg;
-        }
-    }
-
-    /**
-     * Dispatch a service event.
-     * @param event : the service to dispatch
-     */
-    private void fireServiceChanged(ServiceEvent event) {
-        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);
-                ServiceReference sr = event.getServiceReference();
-                if (li.m_filter == null) {
-                    li.m_listener.serviceChanged(event);
-                }
-                if (li.m_filter != null && li.m_filter.match(sr)) {
-                    li.m_listener.serviceChanged(event);
-                }
-            }
-        }
-    }
-
-    /**
-     * Get available (and accessible) service references.
-     * 
-     * @param className : required interface
-     * @param expr : LDAP filter
-     * @return : the list of available service references.
-     * @throws InvalidSyntaxException
-     *             occurs when the LDAP filter is malformed.
-     */
-    public ServiceReference[] getServiceReferences(String className, String expr) throws InvalidSyntaxException {
-        synchronized (m_regs) {
-            // Define filter if expression is not null.
-            Filter filter = null;
-            if (expr != null) {
-                filter = m_bc.createFilter(expr);
-            }
-
-            List refs = new ArrayList();
-
-            for (int i = 0; i < m_regs.size(); i++) {
-                ServiceRegistrationImpl reg = (ServiceRegistrationImpl) m_regs.get(i);
-                // Determine if the registered services matches the search
-                // criteria.
-                boolean matched = false;
-
-                // If className is null, then look at filter only.
-                if ((className == null) && ((filter == null) || filter.match(reg.getReference()))) {
-                    matched = true;
-                } else if (className != null) {
-                    // If className is not null, then first match the
-                    // objectClass property before looking at the
-                    // filter.
-                    String[] objectClass = (String[]) ((ServiceRegistrationImpl) reg).getProperty(Constants.OBJECTCLASS);
-                    for (int classIdx = 0; classIdx < objectClass.length; classIdx++) {
-                        if (objectClass[classIdx].equals(className) && ((filter == null) || filter.match(reg.getReference()))) {
-                            matched = true;
-                            break;
-                        }
-                    }
-                }
-
-                // Add reference if it was a match.
-                if (matched) {
-                    refs.add(reg.getReference());
-                }
-            }
-
-            if (refs.size() > 0) {
-                return (ServiceReference[]) refs.toArray(new ServiceReference[refs.size()]);
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Look for a service reference.
-     * 
-     * @param clazz : required interface.
-     * @return the first available provider or null if none available.
-     */
-    public ServiceReference getServiceReference(String clazz) {
-        synchronized (m_regs) {
-            try {
-                ServiceReference[] refs = getServiceReferences(clazz, null);
-                if (refs != null) {
-                    return refs[0];
-                } // If the refs != null we are sure that it exists one reference or more.
-            } catch (InvalidSyntaxException ex) {
-                System.err.println("Scope Service Registry : Problem when looking for service reference" + ex.getMessage());
-            }
-            return null;
-        }
-    }
-
-    /**
-     * 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 (m_regs) {
-            // Look for the service registration for this ref
-            ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
-            if (reg.isValid()) {
-                // Delegate the service providing to the service registration
-                return reg.getService();
-            } else {
-                return null;
-            }
-        }
-    }
-
-    /**
-     * 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 (m_regs) {
-            // Can delegate on getServiceReference, indeed their is no test on
-            // the "modularity" conflict.
-            return getServiceReferences(clazz, filter);
-        }
-    }
-
-    /**
-     * 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) {
-        // 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) {
-        fireServiceChanged(new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()));
-    }
-
-    /**
-     * Unregister a service.
-     * @param reg : the service registration to unregister
-     */
-    public void unregisterService(ServiceRegistrationImpl reg) {
-        m_regs.remove(reg);
-        fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
-    }
-
-    /**
-     * Reset the service registry.
-     */
-    protected void reset() {
-        m_serviceId = 1L;
-        m_listeners = new ArrayList();
-        m_regs = new ArrayList();
-    }
-}
+/* 
+ * 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.context;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.util.Logger;
+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;
+
+/**
+ * Internal Service Registry. This class is used for in the composition.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceRegistry {
+
+    /**
+     * Service Id index.
+     */
+    private long m_serviceId = 1L;
+
+    /**
+     * List of service listeners.
+     */
+    private List m_listeners = new ArrayList(); // ListenerInfo List
+
+    /**
+     * List of service registration.
+     */
+    private List m_regs = new ArrayList();
+
+    /**
+     * A "real" bundle context to create LDAP filter.
+     */
+    private BundleContext m_context; // BundleContext to create Filter
+    
+    /**
+     * Registry logger.
+     */
+    private Logger m_logger;
+
+    /**
+     * Listener info structure.
+     */
+    private class ListenerInfo {
+        /**
+         * Listener object.
+         */
+        private ServiceListener m_listener;
+        /**
+         * Filter associated with the filter.
+         */
+        private Filter m_filter;
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param context : bundle context.
+     */
+    public ServiceRegistry(BundleContext context) {
+        m_context = context;
+        m_logger = new Logger(m_context, "Registry logger " + m_context.getBundle().getBundleId());
+    }
+
+    /**
+     * Add a given service listener with no filter.
+     * 
+     * @param arg0 : the service listener to add
+     */
+    public void addServiceListener(ServiceListener arg0) {
+        ListenerInfo info = new ListenerInfo();
+        info.m_listener = arg0;
+        info.m_filter = null;
+        m_listeners.add(info);
+    }
+
+    /**
+     * Unget a service.
+     * 
+     * @param instance : instance releasing the service.
+     * @param ref : released reference.
+     * @return true if the unget success
+     */
+    public boolean ungetService(ComponentInstance instance, ServiceReference ref) {
+
+        ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
+        if (reg.isValid()) {
+            reg.ungetService(instance, reg.getService());
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Unregister a service listener.
+     * 
+     * @param arg0 : the service listener to remove
+     */
+    public void removeServiceListener(ServiceListener arg0) {
+        m_listeners.remove(arg0);
+    }
+
+    /**
+     * Register a service.
+     * 
+     * @param instance : provider instance.
+     * @param clazz : provided interface.
+     * @param svcObj : service object of service factory object.
+     * @param dict : service properties.
+     * @return the created service registration.
+     */
+    public ServiceRegistration registerService(ComponentInstance instance, String clazz, Object svcObj, Dictionary dict) {
+        synchronized (m_regs) {
+            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, instance, new String[] { clazz }, new Long(m_serviceId++), svcObj, dict);
+            m_regs.add(reg);
+            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
+            return reg;
+        }
+    }
+
+    /**
+     * Register a service.
+     * 
+     * @param instance : provider instance.
+     * @param clazzes : provided interfaces.
+     * @param svcObj : service object of service factory object.
+     * @param dict : service properties.
+     * @return the created service registration.
+     */
+    public ServiceRegistration registerService(ComponentInstance instance, String[] clazzes, Object svcObj, Dictionary dict) {
+        synchronized (m_regs) {
+            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, instance, clazzes, new Long(m_serviceId++), svcObj, dict);
+            m_regs.add(reg);
+            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
+            return reg;
+        }
+    }
+
+    /**
+     * Dispatch a service event.
+     * @param event : the service to dispatch
+     */
+    private void fireServiceChanged(ServiceEvent event) {
+        synchronized (m_listeners) {
+            // Iterate on the service listener list to notify service listener
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ListenerInfo info = (ListenerInfo) m_listeners.get(i);
+                ServiceReference ref = event.getServiceReference();
+                if (info.m_filter == null) {
+                    info.m_listener.serviceChanged(event);
+                }
+                if (info.m_filter != null && info.m_filter.match(ref)) {
+                    info.m_listener.serviceChanged(event);
+                }
+            }
+        }
+    }
+
+    /**
+     * Get available (and accessible) service references.
+     * 
+     * @param className : required interface
+     * @param expr : LDAP filter
+     * @return : the list of available service references.
+     * @throws InvalidSyntaxException
+     *             occurs when the LDAP filter is malformed.
+     */
+    public ServiceReference[] getServiceReferences(String className, String expr) throws InvalidSyntaxException {
+        synchronized (m_regs) {
+            // Define filter if expression is not null.
+            Filter filter = null;
+            if (expr != null) {
+                filter = m_context.createFilter(expr);
+            }
+
+            List refs = new ArrayList();
+
+            for (int i = 0; i < m_regs.size(); i++) {
+                ServiceRegistrationImpl reg = (ServiceRegistrationImpl) m_regs.get(i);
+                // Determine if the registered services matches the search
+                // criteria.
+                boolean matched = false;
+
+                // If className is null, then look at filter only.
+                if ((className == null) && ((filter == null) || filter.match(reg.getReference()))) {
+                    matched = true;
+                } else if (className != null) {
+                    // If className is not null, then first match the
+                    // objectClass property before looking at the
+                    // filter.
+                    String[] objectClass = (String[]) ((ServiceRegistrationImpl) reg).getProperty(Constants.OBJECTCLASS);
+                    for (int classIdx = 0; classIdx < objectClass.length; classIdx++) {
+                        if (objectClass[classIdx].equals(className) && ((filter == null) || filter.match(reg.getReference()))) {
+                            matched = true;
+                            break;
+                        }
+                    }
+                }
+
+                // Add reference if it was a match.
+                if (matched) {
+                    refs.add(reg.getReference());
+                }
+            }
+
+            if (! refs.isEmpty()) {
+                return (ServiceReference[]) refs.toArray(new ServiceReference[refs.size()]);
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Look for a service reference.
+     * 
+     * @param clazz : required interface.
+     * @return the first available provider or null if none available.
+     */
+    public ServiceReference getServiceReference(String clazz) {
+        synchronized (m_regs) {
+            try {
+                ServiceReference[] refs = getServiceReferences(clazz, null);
+                if (refs != null) {
+                    return refs[0];
+                } // If the refs != null we are sure that it exists one reference or more.
+            } catch (InvalidSyntaxException ex) {
+                // Cannot happen : null filter.
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Get a service object.
+     * @param instance : component instance requiring the service.
+     * @param ref : the required reference.
+     * @return the service object.
+     */
+    public Object getService(ComponentInstance instance, ServiceReference ref) {
+        synchronized (m_regs) {
+            // Look for the service registration for this ref
+            ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
+            if (reg.isValid()) {
+                // Delegate the service providing to the service registration
+                return reg.getService();
+            } else {
+                return null;
+            }
+        }
+    }
+
+    /**
+     * 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 (m_regs) {
+            // Can delegate on getServiceReference, indeed their is no test on
+            // the "modularity" conflict.
+            return getServiceReferences(clazz, filter);
+        }
+    }
+
+    /**
+     * 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) {
+        // If the filter is null, subscribe with no filter.
+        if (filter == null) {
+            addServiceListener(listener);
+            return;
+        }
+        
+        try {
+            ListenerInfo info = new ListenerInfo();
+            info.m_listener = listener;
+            info.m_filter = m_context.createFilter(filter);
+            m_listeners.add(info);
+        } catch (InvalidSyntaxException ex) {
+            m_logger.log(Logger.ERROR, ex.getMessage(), ex);
+        }
+        
+    }
+
+    /**
+     * Dispatch a service properties modified event.
+     * @param reg : the implicated service registration.
+     */
+    public void servicePropertiesModified(ServiceRegistrationImpl reg) {
+        fireServiceChanged(new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()));
+    }
+
+    /**
+     * Unregister a service.
+     * @param reg : the service registration to unregister
+     */
+    public void unregisterService(ServiceRegistrationImpl reg) {
+        m_regs.remove(reg);
+        fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
+    }
+
+    /**
+     * Reset the service registry.
+     */
+    public void reset() {
+        m_serviceId = 1L;
+        m_listeners = new ArrayList();
+        m_regs = new ArrayList();
+    }
+}
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/context/StringMap.java
similarity index 80%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/context/StringMap.java
index bd057aa..31f7331 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/StringMap.java
@@ -1,142 +1,142 @@
-/* 
- * 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;
-
-import java.util.Comparator;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Simple utility class that creates a map for string-based keys by extending
- * <tt>TreeMap</tt>. This map can be set to use case-sensitive or
- * case-insensitive comparison when searching for the key. Any keys put into
- * this map will be converted to a <tt>String</tt> using the
- * <tt>toString()</tt> method, since it is only intended to compare strings.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class StringMap extends TreeMap {
-
-    /**
-     * serialVersionUID.
-     */
-    private static final long serialVersionUID = 6948801857034259744L;
-
-    /**
-     * Constructor.
-     */
-    public StringMap() {
-        this(true);
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param caseSensitive : fix if the map if case sensitive or not.
-     */
-    public StringMap(boolean caseSensitive) {
-        super(new StringComparator(caseSensitive));
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param map : initial properties.
-     * @param caseSensitive : fix if the map if case sensitive or not.
-     */
-    public StringMap(Map map, boolean caseSensitive) {
-        this(caseSensitive);
-        putAll(map);
-    }
-
-    /**
-     * Put a record in the map.
-     * @param key : key
-     * @param value : value
-     * @return an object.
-     * @see java.util.TreeMap#put(K, V)
-     */
-    public Object put(Object key, Object value) {
-        return super.put(key.toString(), value);
-    }
-
-    /**
-     * Check if the map is case-sensitive.
-     * @return true if the map is case sensitive.
-     */
-    public boolean isCaseSensitive() {
-        return ((StringComparator) comparator()).isCaseSensitive();
-    }
-
-    /**
-     * Set the case sensitivity.
-     * 
-     * @param b : the new case sensitivity.
-     */
-    public void setCaseSensitive(boolean b) {
-        ((StringComparator) comparator()).setCaseSensitive(b);
-    }
-
-    private static class StringComparator implements Comparator {
-        /**
-         * Is the map case sensitive?
-         */
-        private boolean m_isCaseSensitive = true;
-
-        /**
-         * Constructor.
-         * 
-         * @param b : true to enable the case sensitivity.
-         */
-        public StringComparator(boolean b) {
-            m_isCaseSensitive = b;
-        }
-
-        /**
-         * Compare to object.
-         * @param o1 : first object to compare
-         * @param o2 : second object to compare
-         * @return the comparison result
-         * @see java.util.Comparator#compare(T, T)
-         */
-        public int compare(Object o1, Object o2) {
-            if (m_isCaseSensitive) {
-                return o1.toString().compareTo(o2.toString());
-            } else {
-                return o1.toString().compareToIgnoreCase(o2.toString());
-            }
-        }
-
-        /**
-         * Check if the comparator is case sensitive.
-         * @return true if the map is case sensitive.
-         */
-        public boolean isCaseSensitive() {
-            return m_isCaseSensitive;
-        }
-
-        /**
-         * Set the case sensitivity.
-         * 
-         * @param b : true to enable the case sensitivity
-         */
-        public void setCaseSensitive(boolean b) {
-            m_isCaseSensitive = b;
-        }
-    }
-}
+/* 
+ * 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.context;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Simple utility class that creates a map for string-based keys by extending
+ * <tt>TreeMap</tt>. This map can be set to use case-sensitive or
+ * case-insensitive comparison when searching for the key. Any keys put into
+ * this map will be converted to a <tt>String</tt> using the
+ * <tt>toString()</tt> method, since it is only intended to compare strings.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class StringMap extends TreeMap {
+
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = 6948801857034259744L;
+
+    /**
+     * Constructor.
+     */
+    public StringMap() {
+        this(true);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param caseSensitive : fix if the map if case sensitive or not.
+     */
+    public StringMap(boolean caseSensitive) {
+        super(new StringComparator(caseSensitive));
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param map : initial properties.
+     * @param caseSensitive : fix if the map if case sensitive or not.
+     */
+    public StringMap(Map map, boolean caseSensitive) {
+        this(caseSensitive);
+        putAll(map);
+    }
+
+    /**
+     * Put a record in the map.
+     * @param key : key
+     * @param value : value
+     * @return an object.
+     * @see java.util.TreeMap#put(K, V)
+     */
+    public Object put(Object key, Object value) {
+        return super.put(key.toString(), value);
+    }
+
+    /**
+     * Check if the map is case-sensitive.
+     * @return true if the map is case sensitive.
+     */
+    public boolean isCaseSensitive() {
+        return ((StringComparator) comparator()).isCaseSensitive();
+    }
+
+    /**
+     * Set the case sensitivity.
+     * 
+     * @param flag : the new case sensitivity.
+     */
+    public void setCaseSensitive(boolean flag) {
+        ((StringComparator) comparator()).setCaseSensitive(flag);
+    }
+
+    private static class StringComparator implements Comparator {
+        /**
+         * Is the map case sensitive?
+         */
+        private boolean m_isCaseSensitive = true;
+
+        /**
+         * Constructor.
+         * 
+         * @param flag : true to enable the case sensitivity.
+         */
+        public StringComparator(boolean flag) {
+            m_isCaseSensitive = flag;
+        }
+
+        /**
+         * Compare to object.
+         * @param object1 : first object to compare
+         * @param object2 : second object to compare
+         * @return the comparison result
+         * @see java.util.Comparator#compare(T, T)
+         */
+        public int compare(Object object1, Object object2) {
+            if (m_isCaseSensitive) {
+                return object1.toString().compareTo(object2.toString());
+            } else {
+                return object1.toString().compareToIgnoreCase(object2.toString());
+            }
+        }
+
+        /**
+         * Check if the comparator is case sensitive.
+         * @return true if the map is case sensitive.
+         */
+        public boolean isCaseSensitive() {
+            return m_isCaseSensitive;
+        }
+
+        /**
+         * Set the case sensitivity.
+         * 
+         * @param flag : true to enable the case sensitivity
+         */
+        public void setCaseSensitive(boolean flag) {
+            m_isCaseSensitive = flag;
+        }
+    }
+}
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 1509cf6..6021c5a 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
@@ -24,7 +24,6 @@
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
 
 /**
  * Architecture Handler : do reflection on your component.
@@ -52,6 +51,7 @@
      * @see org.apache.felix.ipojo.Handler#stop()
      */
     public void stop() {
+        // Nothing do do when stopping.
     }
 
     /**
@@ -59,7 +59,7 @@
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-        log(Logger.INFO, "Start architecture handler with " + m_name + " name");
+        info("Start architecture handler with " + m_name + " name");
     }
 
     /**
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
deleted file mode 100644
index 26db364..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
+++ /dev/null
@@ -1,688 +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.handlers.configuration;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.parser.ParseUtils;
-import org.apache.felix.ipojo.util.Callback;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * Configurable Property.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ConfigurableProperty {
-
-    /**
-     * Name of the property (filed name if not set).
-     */
-    private String m_name;
-
-    /**
-     * Field of the property.
-     */
-    private String m_field;
-
-    /**
-     * Method of the property.
-     */
-    private Callback m_method;
-
-    /**
-     * Value of the property.
-     */
-    private Object m_value;
-
-    /**
-     * Type of the property.
-     */
-    private Class m_type;
-
-    /**
-     * Configuration Handler managing this property.
-     */
-    private ConfigurationHandler m_handler;
-
-    /**
-     * Configurable Property Constructor. At least the method or the field need
-     * to be referenced.
-     * 
-     * @param name : name of the property (optional)
-     * @param field : name of the field
-     * @param method : method name
-     * @param value : initial value of the property (optional)
-     * @param type : the type of the property
-     * @param ch : configuration handler managing this configurable property
-     * @throws ConfigurationException : occurs when the property value cannot be set.
-     */
-    public ConfigurableProperty(String name, String field, String method, String value, String type, ConfigurationHandler ch) throws ConfigurationException {
-        m_handler = ch;
-
-        m_field = field;
-
-        if (name != null) {
-            m_name = name;
-        } else {
-            if (m_field != null) {
-                m_name = field;
-            } else {
-                m_name = method;
-            }
-        }
-        m_field = field;
-
-        if (value != null) {
-            setValue(value, type);
-        } else {
-            setType(type);
-        }
-
-        if (method != null) {
-            m_method = new Callback(method, new String[] { m_type.getName() }, false, m_handler.getInstanceManager());
-        }
-
-    }
-
-    /**
-     * The set type method fix the property type according to the given type name.
-     * @param type : the type name
-     * @throws ConfigurationException if an error occurs when loading the type class for non-primitive types.
-     */
-    private void setType(String type) throws ConfigurationException {
-        // Syntactic sugar to avoid writing java.lang.String
-        if ("string".equals(type) || "String".equals(type)) {
-            m_type = java.lang.String.class;
-            return;
-        }
-        if (type.equals("boolean")) {
-            m_type = Boolean.TYPE;
-            return;
-        }
-        if ("byte".equals(type)) {
-            m_type = Byte.TYPE;
-            return;
-        }
-        if ("short".equals(type)) {
-            m_type = Short.TYPE;
-            return;
-        }
-        if ("int".equals(type)) {
-            m_type = Integer.TYPE;
-            return;
-        }
-        if ("long".equals(type)) {
-            m_type = Long.TYPE;
-            return;
-        }
-        if ("float".equals(type)) {
-            m_type = Float.TYPE;
-            return;
-        }
-        if ("double".equals(type)) {
-            m_type = Double.TYPE;
-            return;
-        }
-        if ("char".equals(type)) {
-            m_type = Character.TYPE;
-            return;
-        }
-
-        // Array :
-        if (type.endsWith("[]")) {
-            String internalType = type.substring(0, type.length() - 2);
-            if ("string".equals(internalType) || "String".equals(internalType)) {
-                m_type = new String[0].getClass();
-                return;
-            }
-            if ("boolean".equals(internalType)) {
-                m_type = new boolean[0].getClass();
-                return;
-            }
-            if ("byte".equals(internalType)) {
-                m_type = new byte[0].getClass();
-                return;
-            }
-            if ("short".equals(internalType)) {
-                m_type = new short[0].getClass();
-                return;
-            }
-            if ("int".equals(internalType)) {
-                m_type = new int[0].getClass();
-                return;
-            }
-            if ("long".equals(internalType)) {
-                m_type = new long[0].getClass();
-                return;
-            }
-            if ("float".equals(internalType)) {
-                m_type = new float[0].getClass();
-                return;
-            }
-            if ("double".equals(internalType)) {
-                m_type = new double[0].getClass();
-                return;
-            }
-            if ("char".equals(internalType)) {
-                m_type = new char[0].getClass();
-                return;
-            }
-
-            // Complex array type.
-            try {
-                Class c = m_handler.getInstanceManager().getContext().getBundle().loadClass(internalType);
-                Object[] ob = (Object[]) Array.newInstance(c, 0);
-                m_type = ob.getClass();
-                return;
-            } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Class not found exception in setValue on " + internalType);
-            } catch (SecurityException e) {
-                throw new ConfigurationException("Secutiry Exception in setValue on " + internalType);
-            } catch (IllegalArgumentException e) {
-                throw new ConfigurationException("Argument problem to call the constructor of the type " + internalType);
-            }
-        }
-
-        // Non array, complex type.
-        try {
-            m_type = m_handler.getInstanceManager().getContext().getBundle().loadClass(type);
-        } catch (ClassNotFoundException e) {
-            throw new ConfigurationException("Class not found exception in setValue on " + type + " : " + e.getMessage());
-        } catch (SecurityException e) {
-            throw new ConfigurationException("Security excption in setValue on " + type + " : " + e.getMessage());
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
-        }
-    }
-
-    /**
-     * Set the value of the property.
-     * @param strValue : value of the property (String)
-     * @param type : type of the property
-     * @throws ConfigurationException : occurs when the property value cannot be initialized.
-     */
-    private void setValue(String strValue, String type) throws ConfigurationException {
-        Object value = null;
-
-        // Syntactic sugar to avoid writing java.lang.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 ("byte".equals(type)) {
-            value = new Byte(strValue);
-            m_type = Byte.TYPE;
-        }
-        if ("short".equals(type)) {
-            value = new Short(strValue);
-            m_type = Short.TYPE;
-        }
-        if ("int".equals(type)) {
-            value = new Integer(strValue);
-            m_type = Integer.TYPE;
-        }
-        if ("long".equals(type)) {
-            value = new Long(strValue);
-            m_type = Long.TYPE;
-        }
-        if ("float".equals(type)) {
-            value = new Float(strValue);
-            m_type = Float.TYPE;
-        }
-        if ("double".equals(type)) {
-            value = new Double(strValue);
-            m_type = Double.TYPE;
-        }
-        if ("char".equals(type)) {
-            value = new Character(strValue.charAt(0));
-            m_type = Character.TYPE;
-        }
-
-        // Array :
-        if (type.endsWith("[]")) {
-            String internalType = type.substring(0, type.length() - 2);
-            setArrayValue(internalType, ParseUtils.parseArrays(strValue));
-            return;
-        }
-
-        if (value == null) {
-            // Else it is a neither a primitive type neither a String -> create
-            // the object by calling a constructor with a string in argument.
-            try {
-                m_type = m_handler.getInstanceManager().getContext().getBundle().loadClass(type);
-                Constructor cst = m_type.getConstructor(new Class[] { String.class });
-                value = cst.newInstance(new Object[] { strValue });
-            } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Class not found exception in setValue on " + type + " : " + e.getMessage());
-            } catch (SecurityException e) {
-                throw new ConfigurationException("Security excption in setValue on " + type + " : " + e.getMessage());
-            } catch (NoSuchMethodException e) {
-                throw new ConfigurationException("Constructor not found exeption in setValue on " + type + " : " + e.getMessage());
-            } catch (IllegalArgumentException e) {
-                throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
-            } catch (InstantiationException e) {
-                throw new ConfigurationException("Instantiation problem  " + type);
-            } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Illegal Access " + type);
-            } catch (InvocationTargetException e) {
-                throw new ConfigurationException("Invocation problem " + type + " : " + e.getTargetException().getMessage());
-            }
-        }
-
-        m_value = value;
-
-    }
-
-    /**
-     * Set array value to the current property.
-     * 
-     * @param internalType : type of the property
-     * @param values : new property value
-     * @throws ConfigurationException occurs when the array cannot be initialized
-     */
-    private void setArrayValue(String internalType, String[] values) throws ConfigurationException {
-        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]);
-            }
-            m_value = str;
-            m_type = new String[0].getClass();
-            return;
-        }
-        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();
-            }
-            m_value = bool;
-            m_type = new boolean[0].getClass();
-            return;
-        }
-        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();
-            }
-            m_value = byt;
-            m_type = new byte[0].getClass();
-            return;
-        }
-        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();
-            }
-            m_value = shor;
-            m_type = new short[0].getClass();
-            return;
-        }
-        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();
-            }
-            m_value = in;
-            m_type = new int[0].getClass();
-            return;
-        }
-        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();
-            }
-            m_value = ll;
-            m_type = new long[0].getClass();
-            return;
-        }
-        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();
-            }
-            m_value = fl;
-            m_type = new float[0].getClass();
-            return;
-        }
-        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();
-            }
-            m_value = dl;
-            m_type = new double[0].getClass();
-            return;
-        }
-        if ("char".equals(internalType)) {
-            char[] dl = new char[values.length];
-            for (int i = 0; i < values.length; i++) {
-                dl[i] = values[i].toCharArray()[0];
-            }
-            m_value = dl;
-            m_type = new char[0].getClass();
-            return;
-        }
-
-        // Else it is a neither a primitive type neither a String -> create the
-        // object by calling a constructor with a string in argument.
-        try {
-            Class c = m_handler.getInstanceManager().getContext().getBundle().loadClass(internalType);
-            Constructor cst = c.getConstructor(new Class[] { String.class });
-            Object[] ob = (Object[]) Array.newInstance(c, values.length);
-            for (int i = 0; i < values.length; i++) {
-                ob[i] = cst.newInstance(new Object[] { values[i].trim() });
-            }
-            m_value = ob;
-            m_type = ob.getClass();
-            return;
-        } catch (ClassNotFoundException e) {
-            throw new ConfigurationException("Class not found exception in setValue on " + internalType);
-        } catch (SecurityException e) {
-            throw new ConfigurationException("Secutiry Exception in setValue on " + internalType);
-        } catch (NoSuchMethodException e) {
-            throw new ConfigurationException("Constructor not found exception in setValue on " + internalType);
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException("Argument problem to call the constructor of the type " + internalType);
-        } catch (InstantiationException e) {
-            throw new ConfigurationException("Instantiation problem  " + internalType);
-        } catch (IllegalAccessException e) {
-            throw new ConfigurationException("Illegal Access Exception in  " + internalType);
-        } catch (InvocationTargetException e) {
-            throw new ConfigurationException("Invocation problem " + internalType + " : " + e.getTargetException().getMessage());
-        }
-    }
-
-    public String getName() {
-        return m_name;
-    }
-
-    public String getField() {
-        return m_field;
-    }
-
-    /**
-     * Get method name, null if no method.
-     * @return the method name.
-     */
-    public String getMethod() {
-        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() {
-        return m_value;
-    }
-
-    /**
-     * Fix the value of the property.
-     * @param value : the new value.
-     */
-    public void setValue(Object value) {
-        // Is the object is directly assignable to the property, affect it.
-        if (isAssignable(m_type, value)) {
-            m_value = value;
-        } else {
-            // If the object is a String, we must recreate the object from the String form
-            if (value instanceof String) {
-                try {
-                    m_value = create(m_type, (String) value);
-                } catch (ConfigurationException e) {
-                    throw new ClassCastException("Incompatible type for the property " + m_name + " : " + e.getMessage());
-                }
-            } else {
-                // Error, the given property cannot be injected.
-                throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type.getName() + " expected, " + value.getClass() + " received");
-            }
-        }
-    }
-    
-    /**
-     * Test if the given value is assignable to the given type.
-     * @param type : class of the type
-     * @param value : object to check
-     * @return true if the object is assignable in the property of type 'type'.
-     */
-    public static boolean isAssignable(Class type, Object value) {
-        if (type.isInstance(value)) {
-            return true;
-        } else if (type.isPrimitive()) {
-            // Manage all boxing types.
-            if (value instanceof Boolean && type.equals(Boolean.TYPE)) {
-                return true;
-            }
-            if (value instanceof Byte && type.equals(Byte.TYPE)) {
-                return true;
-            }
-            if (value instanceof Short && type.equals(Short.TYPE)) {
-                return true;
-            }
-            if (value instanceof Integer && type.equals(Integer.TYPE)) {
-                return true;
-            }
-            if (value instanceof Long && type.equals(Long.TYPE)) {
-                return true;
-            }
-            if (value instanceof Float && type.equals(Float.TYPE)) {
-                return true;
-            }
-            if (value instanceof Double && type.equals(Double.TYPE)) {
-                return true;
-            }
-            if (value instanceof Character && type.equals(Character.TYPE)) {
-                return true;
-            }
-            return false;
-        } else {
-            // Else return false.
-            return false;
-        }
-    }
-
-    /**
-     * Create an object of the given type with the given String value.
-     * @param type : type of the returned object
-     * @param strValue : String value.
-     * @return the object of type 'type' created from the String 'value'
-     * @throws ConfigurationException occurs when the object cannot be created.
-     */
-    public static Object create(Class type, String strValue) throws ConfigurationException {
-        if (type.equals(Boolean.TYPE)) { return new Boolean(strValue); }
-        if (type.equals(Byte.TYPE)) { return new Byte(strValue); }
-        if (type.equals(Short.TYPE)) { return new Short(strValue); }
-        if (type.equals(Integer.TYPE)) { return new Integer(strValue); }
-        if (type.equals(Long.TYPE)) { return new Long(strValue); }
-        if (type.equals(Float.TYPE)) { return new Float(strValue); }
-        if (type.equals(Double.TYPE)) { return new Double(strValue); }
-        if (type.equals(Character.TYPE)) { return new Character(strValue.charAt(0)); }
-
-        // Array :
-        if (type.isArray()) { return createArrayObject(type.getComponentType(), ParseUtils.parseArrays(strValue)); }
-        // Else it is a neither a primitive type neither a String -> create
-        // the object by calling a constructor with a string in argument.
-        try {
-            Constructor cst = type.getConstructor(new Class[] { String.class });
-            return cst.newInstance(new Object[] { strValue });
-        } catch (SecurityException e) {
-            throw new ConfigurationException("Security exception in create on " + type + " : " + e.getMessage());
-        } catch (NoSuchMethodException e) {
-            throw new ConfigurationException("Constructor not found exception in create on " + type + " : " + e.getMessage());
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
-        } catch (InstantiationException e) {
-            throw new ConfigurationException("Instantiation problem  " + type);
-        } catch (IllegalAccessException e) {
-            throw new ConfigurationException("Illegal Access " + type);
-        } catch (InvocationTargetException e) {
-            throw new ConfigurationException("Invocation problem " + type + " : " + e.getTargetException().getMessage());
-        }
-
-    }
-
-    /**
-     * Create an array object containing the type 'interntype' from the String array 'values'.
-     * @param interntype : internal type of the array.
-     * @param values : String array
-     * @return the array containing objects created from the 'values' array
-     * @throws ConfigurationException occurs when the array cannot be created correctly
-     */
-    public static Object createArrayObject(Class interntype, String[] values) throws ConfigurationException {
-        if (interntype.equals(Boolean.TYPE)) {
-            boolean[] bool = new boolean[values.length];
-            for (int i = 0; i < values.length; i++) {
-                bool[i] = new Boolean(values[i]).booleanValue();
-            }
-            return bool;
-        }
-        if (interntype.equals(Byte.TYPE)) {
-            byte[] byt = new byte[values.length];
-            for (int i = 0; i < values.length; i++) {
-                byt[i] = new Byte(values[i]).byteValue();
-            }
-            return byt;
-        }
-        if (interntype.equals(Short.TYPE)) {
-            short[] shor = new short[values.length];
-            for (int i = 0; i < values.length; i++) {
-                shor[i] = new Short(values[i]).shortValue();
-            }
-            return shor;
-        }
-        if (interntype.equals(Integer.TYPE)) {
-            int[] in = new int[values.length];
-            for (int i = 0; i < values.length; i++) {
-                in[i] = new Integer(values[i]).intValue();
-            }
-            return in;
-        }
-        if (interntype.equals(Long.TYPE)) {
-            long[] ll = new long[values.length];
-            for (int i = 0; i < values.length; i++) {
-                ll[i] = new Long(values[i]).longValue();
-            }
-            return ll;
-        }
-        if (interntype.equals(Float.TYPE)) {
-            float[] fl = new float[values.length];
-            for (int i = 0; i < values.length; i++) {
-                fl[i] = new Float(values[i]).floatValue();
-            }
-            return fl;
-        }
-        if (interntype.equals(Double.TYPE)) {
-            double[] dl = new double[values.length];
-            for (int i = 0; i < values.length; i++) {
-                dl[i] = new Double(values[i]).doubleValue();
-            }
-            return dl;
-        }
-        if (interntype.equals(Character.TYPE)) {
-            char[] dl = new char[values.length];
-            for (int i = 0; i < values.length; i++) {
-                dl[i] = values[i].toCharArray()[0];
-            }
-            return dl;
-        }
-
-        // Else it is a neither a primitive type -> create the
-        // object by calling a constructor with a string in argument.
-        try {
-            Constructor cst = interntype.getConstructor(new Class[] { String.class });
-            Object[] ob = (Object[]) Array.newInstance(interntype, values.length);
-            for (int i = 0; i < values.length; i++) {
-                ob[i] = cst.newInstance(new Object[] { values[i].trim() });
-            }
-            return ob;
-        } catch (NoSuchMethodException e) {
-            throw new ConfigurationException("Constructor not found exception in setValue on " + interntype.getName());
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException("Argument problem to call the constructor of the type " + interntype.getName());
-        } catch (InstantiationException e) {
-            throw new ConfigurationException("Instantiation problem  " + interntype.getName());
-        } catch (IllegalAccessException e) {
-            throw new ConfigurationException("Illegal Access Exception in  " + interntype.getName());
-        } catch (InvocationTargetException e) {
-            throw new ConfigurationException("Invocation problem " + interntype.getName() + " : " + e.getTargetException().getMessage());
-        }
-    }
-
-    /**
-     * Invoke the method (if specified).
-     * If the invocation failed, the instance is stopped.
-     */
-    public void invoke() {
-        try {
-            m_method.call(new Object[] { m_value });
-        } catch (NoSuchMethodException e) {
-            m_handler.log(Logger.ERROR, "The method " + m_method + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-            m_handler.getInstanceManager().stop();
-        } catch (IllegalAccessException e) {
-            m_handler.log(Logger.ERROR, "The method " + m_method + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-            m_handler.getInstanceManager().stop();
-        } catch (InvocationTargetException e) {
-            m_handler.log(Logger.ERROR, "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-            m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-
-    /**
-     * Handler createInstance method. This method is override to allow delayed callback invocation.
-     * If the invocation failed, the instance is stopped.
-     * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
-     */
-    public void invoke(Object instance) {
-        try {
-            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().stop();
-        } 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().stop();
-        } 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.getTargetException().getMessage());
-            m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-}
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 186caa9..ef89f07 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
@@ -18,24 +18,23 @@
  */
 package org.apache.felix.ipojo.handlers.configuration;
 
-import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Enumeration;
-import java.util.List;
 import java.util.Properties;
 
 import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.IPojoConfiguration;
+import org.apache.felix.ipojo.HandlerFactory;
 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.ComponentTypeDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Property;
 
 /**
  * Handler managing the Configuration Admin.
@@ -46,7 +45,7 @@
     /**
      * List of the configurable fields.
      */
-    private ConfigurableProperty[] m_configurableProperties = new ConfigurableProperty[0];
+    private Property[] m_configurableProperties = new Property[0];
 
     /**
      * ProvidedServiceHandler of the component. It is useful to propagate
@@ -71,16 +70,16 @@
 
     /**
      * Initialize the component type.
-     * @param cd : component type description to populate.
+     * @param desc : 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)
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
      */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
         Element[] confs = metadata.getElements("Properties", "");
-        if (confs.length == 0) { return; }
+        if (confs == null) { return; }
         Element[] configurables = confs[0].getElements("Property");
-        for (int i = 0; i < configurables.length; i++) {
+        for (int i = 0; configurables != null && i < configurables.length; i++) {
             String fieldName = configurables[i].getAttribute("field");
             String methodName = configurables[i].getAttribute("method");
             
@@ -90,10 +89,10 @@
 
             String name = configurables[i].getAttribute("name");
             if (name == null) {
-                if (fieldName != null) {
-                    name = fieldName;
-                } else {
+                if (fieldName == null) {
                     name = methodName;
+                } else {
+                    name = fieldName;
                 }
                 configurables[i].addAttribute(new Attribute("name", name)); // Add the type to avoid configure checking
             }
@@ -101,35 +100,43 @@
             String value = configurables[i].getAttribute("value");
 
             // Detect the type of the property
-            ManipulationMetadata manipulation = new ManipulationMetadata(metadata);
+            PojoMetadata manipulation = getFactory().getPojoMetadata();
             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"); }
-                type = fm.getFieldType();
-                configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
-            } else {
-                MethodMetadata[] mm = manipulation.getMethods(methodName);
-                if (mm.length != 0) {
-                    if (mm[0].getMethodArguments().length != 1) {
-                        throw new ConfigurationException("Malformed property :  The method " + methodName + " does not have one argument");
-                    }
-                    if (type != null && !type.equals(mm[0].getMethodArguments()[0])) {
-                        throw new ConfigurationException("Malformed property :   The field type (" + type + ") and the method type (" + mm[0].getMethodArguments()[0] + ") are not the same.");
-                    }
-                    type = mm[0].getMethodArguments()[0];
-                    configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
-                } else {
+            if (fieldName == null) {
+                MethodMetadata[] method = manipulation.getMethods(methodName);
+                if (method.length == 0) {
                     type = configurables[i].getAttribute("type");
                     if (type == null) {
                         throw new ConfigurationException("Malformed property : The type of the property cannot be discovered, please add a 'type' attribute");
                     }
+                } else {
+                    if (method[0].getMethodArguments().length != 1) {
+                        throw new ConfigurationException("Malformed property :  The method " + methodName + " does not have one argument");
+                    }
+                    if (type != null && !type.equals(method[0].getMethodArguments()[0])) {
+                        throw new ConfigurationException("Malformed property :   The field type (" + type + ") and the method type (" + method[0].getMethodArguments()[0] + ") are not the same.");
+                    }
+                    type = method[0].getMethodArguments()[0];
+                    configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
                 }
-            }
-            if (value != null) {
-                cd.addProperty(new PropertyDescription(name, type, value));
             } else {
-                cd.addProperty(new PropertyDescription(name, type, null));
+                FieldMetadata field = manipulation.getField(fieldName);
+                if (field == null) { throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation"); }
+                type = field.getFieldType();
+                configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
+            }
+            
+            // Is the property set to immutable
+            boolean immutable = false;
+            String imm = configurables[i].getAttribute("immutable");
+            if (imm != null && imm.equalsIgnoreCase("true")) {
+                immutable = true;
+            }
+            
+            if (value == null) {
+                desc.addProperty(new PropertyDescription(name, type, null, false)); // Cannot be immutable if we have no value.
+            } else {
+                desc.addProperty(new PropertyDescription(name, type, value, immutable));
             }
         }
     }
@@ -145,7 +152,7 @@
      */
     public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
         // Store the component manager
-        m_configurableProperties = new ConfigurableProperty[0];
+        m_configurableProperties = new Property[0];
 
         // Build the map
         Element[] confs = metadata.getElements("Properties", "");
@@ -160,43 +167,32 @@
             m_toPropagate = configuration;
         }
 
-        List ff = new ArrayList();
-
-        for (int i = 0; i < configurables.length; i++) {
+        for (int i = 0; configurables != null && i < configurables.length; i++) {
             String fieldName = configurables[i].getAttribute("field");
             String methodName = configurables[i].getAttribute("method");
 
             String name = configurables[i].getAttribute("name"); // The initialize method has fixed the property name.
             String value = configurables[i].getAttribute("value");
 
-            if (configuration.get(name) != null && configuration.get(name) instanceof String) {
-                value = (String) configuration.get(name);
-            } else {
-                if (fieldName != null && configuration.get(fieldName) != null && configuration.get(fieldName) instanceof String) {
-                    value = (String) configuration.get(fieldName);
-                }
-            }
-
             String type = configurables[i].getAttribute("type"); // The initialize method has fixed the property name.
             
-            if (fieldName != null) {
-                FieldMetadata fm = new FieldMetadata(fieldName, type);
-                ff.add(fm);
-            }
-            
-            ConfigurableProperty cp = new ConfigurableProperty(name, fieldName, methodName, value, type, this);
-            addProperty(cp);
+            Property prop = new Property(name, fieldName, methodName, value, type, getInstanceManager(), this);
+            addProperty(prop);
 
             // Check if the instance configuration contains value for the current property :
-            if (configuration.get(name) != null && !(configuration.get(name) instanceof String)) {
-                cp.setValue(configuration.get(name));
-            } else {
-                if (fieldName != null && configuration.get(fieldName) != null && !(configuration.get(fieldName) instanceof String)) {
-                    cp.setValue(configuration.get(fieldName));
+            if (configuration.get(name) == null) {
+                if (fieldName != null && configuration.get(fieldName) != null) {
+                    prop.setValue(configuration.get(fieldName));
                 }
+            } else {
+                prop.setValue(configuration.get(name));
+            }
+            
+            if (fieldName != null) {
+                FieldMetadata field = new FieldMetadata(fieldName, type);
+                getInstanceManager().register(field, prop);
             }
         }
-        getInstanceManager().register(this, (FieldMetadata[]) ff.toArray(new FieldMetadata[ff.size()]), null);
     }
 
     /**
@@ -205,6 +201,7 @@
       * @see org.apache.felix.ipojo.Handler#stop()
       */
     public void stop() {
+        // Nothing to do.
     }
 
     /**
@@ -214,7 +211,7 @@
      */
     public void start() {
         // Get the provided service handler :
-        m_providedServiceHandler = (ProvidedServiceHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":provides");
+        m_providedServiceHandler = (ProvidedServiceHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":provides");
 
         // Propagation
         if (m_isConfigurable) {
@@ -225,45 +222,47 @@
         }
     }
 
-    /**
-     * Setter Callback Method.
-     * Check if the modified field is a configurable 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)
-     */
-    public void setterCallback(String fieldName, Object value) {
-        // Verify that the field name correspond to a configurable property
-        for (int i = 0; i < m_configurableProperties.length; i++) {
-            ConfigurableProperty cp = m_configurableProperties[i];
-            if (cp.hasField() && cp.getField().equals(fieldName)) {
-                // Check if the value has changed
-                if (cp.getValue() == null || !cp.getValue().equals(value)) {
-                    cp.setValue(value); // Change the value
-                }
-            }
-        }
-        // Else do nothing
-    }
-
-    /**
-     * Getter Callback Method.
-     * Check if the field is a configurable property to push the stored value.
-     * @param fieldName : field name
-     * @param value : value pushed by the previous handler
-     * @return the stored value or the previous value.
-     * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String,
-     * java.lang.Object)
-     */
-    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 (fieldName.equals(m_configurableProperties[i].getField())) { 
-                return m_configurableProperties[i].getValue(); 
-            }
-        }
-        return value;
-    }
+//    /**
+//     * Setter Callback Method.
+//     * Check if the modified field is a configurable property to update the value.
+//     * @param pojo : the pojo object on which the field is accessed
+//     * @param fieldName : field name
+//     * @param value : new value
+//     * @see org.apache.felix.ipojo.Handler#onSet(Object, java.lang.String, java.lang.Object)
+//     */
+//    public void onSet(Object pojo, String fieldName, Object value) {
+//        // Verify that the field name correspond to a configurable property
+//        for (int i = 0; i < m_configurableProperties.length; i++) {
+//            Property prop = m_configurableProperties[i];
+//            if (prop.hasField() && prop.getField().equals(fieldName)) {
+//                // Check if the value has changed
+//                if (prop.getValue() == null || !prop.getValue().equals(value)) {
+//                    prop.setValue(value); // Change the value
+//                }
+//            }
+//        }
+//        // Else do nothing
+//    }
+//
+//    /**
+//     * Getter Callback Method.
+//     * Check if the field is a configurable property to push the stored value.
+//     * @param pojo : the pojo object on which the field is accessed
+//     * @param fieldName : field name
+//     * @param value : value pushed by the previous handler
+//     * @return the stored value or the previous value.
+//     * @see org.apache.felix.ipojo.Handler#onGet(Object,
+//     * java.lang.String, java.lang.Object)
+//     */
+//    public Object onGet(Object pojo, String fieldName, Object value) {
+//        // Check if the field is a configurable property
+//        for (int i = 0; i < m_configurableProperties.length; i++) {
+//            if (fieldName.equals(m_configurableProperties[i].getField())) { 
+//                return m_configurableProperties[i].getValue(); 
+//            }
+//        }
+//        return value;
+//    }
 
     /**
      * Handler state changed.
@@ -284,20 +283,20 @@
     /**
      * Add the given property metadata to the property metadata list.
      * 
-     * @param p : property metadata to add
+     * @param prop : property metadata to add
      */
-    protected void addProperty(ConfigurableProperty p) {
+    protected void addProperty(Property prop) {
         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(prop.getName())) { return; }
         }
 
         if (m_configurableProperties.length > 0) {
-            ConfigurableProperty[] newProp = new ConfigurableProperty[m_configurableProperties.length + 1];
+            Property[] newProp = new Property[m_configurableProperties.length + 1];
             System.arraycopy(m_configurableProperties, 0, newProp, 0, m_configurableProperties.length);
-            newProp[m_configurableProperties.length] = p;
+            newProp[m_configurableProperties.length] = prop;
             m_configurableProperties = newProp;
         } else {
-            m_configurableProperties = new ConfigurableProperty[] { p };
+            m_configurableProperties = new Property[] { prop };
         }
     }
 
@@ -317,31 +316,31 @@
     /**
      * Reconfigure the component instance.
      * Check if the new configuration modify the current configuration.
-     * @param np : the new configuration
+     * @param configuration : the new configuration
      * @see org.apache.felix.ipojo.Handler#reconfigure(java.util.Dictionary)
      */
-    public void reconfigure(Dictionary np) {
+    public void reconfigure(Dictionary configuration) {
         Properties toPropagate = new Properties();
-        Enumeration keysEnumeration = np.keys();
+        Enumeration keysEnumeration = configuration.keys();
         while (keysEnumeration.hasMoreElements()) {
             String name = (String) keysEnumeration.nextElement();
-            Object value = np.get(name);
+            Object value = configuration.get(name);
             boolean found = false;
             // Check if the name is a configurable property
-            for (int i = 0; !found && i < m_configurableProperties.length; i++) {
+            for (int i = 0; i < m_configurableProperties.length; i++) {
                 if (m_configurableProperties[i].getName().equals(name)) {
                     // Check if the value has changed
                     if (m_configurableProperties[i].getValue() == null || !m_configurableProperties[i].getValue().equals(value)) {
                         if (m_configurableProperties[i].hasField()) {
-                            getInstanceManager().setterCallback(m_configurableProperties[i].getField(), value); // dispatch that the value has changed
+                            getInstanceManager().onSet(null, m_configurableProperties[i].getField(), value); // dispatch that the value has changed
                         }
                         if (m_configurableProperties[i].hasMethod()) {
                             m_configurableProperties[i].setValue(value);
-                            m_configurableProperties[i].invoke();
+                            m_configurableProperties[i].invoke(null); // Call on all created pojo objects.
                         }
                     }
                     found = true;
-                    // Else do nothing
+                    break;
                 }
             }
             if (!found) {
@@ -366,9 +365,9 @@
      * Handler createInstance method.
      * This method is override to allow delayed callback invocation.
      * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)
      */
-    public void objectCreated(Object instance) {
+    public void onCreation(Object instance) {
         for (int i = 0; i < m_configurableProperties.length; i++) {
             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 7258e23..9b3c0e3 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
@@ -20,62 +20,28 @@
 
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.List;
 
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.IPojoContext;
+import org.apache.felix.ipojo.FieldInterceptor;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.MethodInterceptor;
 import org.apache.felix.ipojo.Nullable;
 import org.apache.felix.ipojo.PolicyServiceContext;
-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.ServiceReferenceRankingComparator;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.apache.felix.ipojo.handlers.dependency.ServiceUsage.Usage;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
 /**
  * Represent a service dependency of the component instance.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class Dependency implements TrackerCustomizer {
-
-    /**
-     * Dependency State : RESOLVED.
-     */
-    public static final int RESOLVED = 1;
-
-    /**
-     * Dependency State : UNRESOLVED.
-     */
-    public static final int UNRESOLVED = 2;
-    
-    /**
-     * Dependency State : BROKEN.
-     * Broken means that a used service disappears for static dependency.
-     */
-    public static final int BROKEN = 3;
-    
-    /**
-     * Dynamic Binding Policy (default).
-     */
-    public static final int DYNAMIC_POLICY = 0;
-
-    /**
-     * Dynamic Priority Binding Policy.
-     */
-    public static final int DYNAMIC_PRIORITY_POLICY = 1;
-    
-    /**
-     * Static Binding Policy.
-     */
-    public static final int STATIC_POLICY = 2;
+public class Dependency extends DependencyModel implements FieldInterceptor, MethodInterceptor {
 
     /**
      * Reference on the Dependency Handler.
@@ -90,144 +56,88 @@
     /**
      * List of dependency callback.
      */
-    private DependencyCallback[] m_callbacks = new DependencyCallback[0];
+    private DependencyCallback[] m_callbacks;
 
     /**
-     * Service Specification required by the dependency.
-     */
-    private String m_specification;
-    
-    /**
-     * Dependency ID (declared ID, if not declare use the specification).
-     */
-    private String m_id;
-
-    /**
-     * Is the dependency a multiple dependency ?
-     */
-    private boolean m_isAggregate = false;
-
-    /**
-     * Is the Dependency an optional dependency ?
-     */
-    private boolean m_isOptional = false;
-
-    /**
-     * LDAP Filter of the Dependency (String form).
-     */
-    private String m_strFilter;
-    
-    /**
      * Is the dependency a service level dependency.
      */
-    private boolean m_isServiceLevelRequirement = false;
-    
-    /**
-     * Resolution policy.
-     */
-    private int m_policy = PolicyServiceContext.LOCAL_AND_GLOBAL; 
+    private boolean m_isServiceLevelRequirement;
 
     /**
-     * Array of service references.
-     * m_ref : Array
+     * Is the provider set frozen ?
      */
-    private List m_references = new ArrayList();
-    
-    /**
-     * Array of service reference containing used service references. 
-     */
-    private List m_usedReferences = new ArrayList();
+    private boolean m_isFrozen;
 
     /**
-     * State of the dependency. 0 : stopped, 1 : valid, 2 : invalid. 
-     * m_state : int
+     * Is the dependency started ?
      */
-    private int m_state;
+    private boolean m_isStarted;
 
     /**
-     * Class of the dependency. 
-     * Useful to create in the case of multiple dependency
-     */
-    private Class m_clazz;
-
-    /**
-     * LDAP Filter of the dependency.
-     */
-    private Filter m_filter;
-    
-    /**
-     * Service Context in which resolving the dependency.
-     */
-    private ServiceContext m_serviceContext;
-    
-    /**
      * Thread Local.
      */
-    private ServiceUsage m_usage = new ServiceUsage();
+    private ServiceUsage m_usage;
 
     /**
-     * Service Tracker.
-     */
-    private Tracker m_tracker;
-    
-    /**
-     * IS the instance activated ? 
-     */
-    private boolean m_activated = false;
-    
-    /**
-     * Binding Policy.
-     */
-    private int m_bindingPolicy;
-    
-    /**
      * Nullable object.
      */
     private Object m_nullable;
-    
+
     /**
      * Default-Implementation.
      */
     private String m_di;
 
     /**
+     * Id of the dependency.
+     */
+    private String m_id;
+
+    /**
      * Dependency constructor. After the creation the dependency is not started.
      * 
-     * @param dh : the dependency handler managing this dependency
+     * @param handler : the dependency handler managing this dependency
      * @param field : field of the dependency
      * @param spec : required specification
      * @param filter : LDAP filter of the dependency
      * @param isOptional : is the dependency an optional dependency ?
      * @param isAggregate : is the dependency an aggregate dependency
-     * @param id : id of the dependency, may be null
+     * @param identity : id of the dependency, may be null
+     * @param context : bundle context (or service context) to use.
      * @param policy : resolution policy
-     * @param bindingPolicy : binding policy
-     * @param di : default-implementation class
+     * @param cmp : comparator to sort references
+     * @param defaultImplem : default-implementation class
      */
-    public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional, boolean isAggregate, String id, int policy, int bindingPolicy, String di) {
-        m_handler = dh;
-        m_field = field;
-        m_specification = spec;
-        m_isOptional = isOptional;
-        m_di = di;
-       
-        m_strFilter = filter;
-        m_isAggregate = isAggregate;
-        if (m_id == null) {
-            m_id = m_specification;
+    public Dependency(DependencyHandler handler, String field, Class spec, Filter filter, boolean isOptional, boolean isAggregate, String identity, BundleContext context, int policy, Comparator cmp, String defaultImplem) {
+        super(spec, isAggregate, isOptional, filter, cmp, policy, context, handler);
+        m_handler = handler;
+        if (field != null) {
+            m_field = field;
+            m_usage = new ServiceUsage();
+        }
+        m_di = defaultImplem;
+
+        if (identity == null) {
+            if (spec != null) {
+                m_id = spec.getName();
+            }
         } else {
-            m_id = id;
-        }
-        if (policy != -1) {
-            m_policy = policy;
-        }
-        
-        m_bindingPolicy = bindingPolicy;
-        
-        // Fix the policy according to the level
-        if ((m_policy == PolicyServiceContext.LOCAL_AND_GLOBAL || m_policy == PolicyServiceContext.LOCAL) && ! ((((IPojoContext) m_handler.getInstanceManager().getContext()).getServiceContext()) instanceof CompositeServiceContext)) {
-            // We are not in a composite : BOTH | STRICT => GLOBAL
-            m_policy = PolicyServiceContext.GLOBAL;
+            m_id = identity;
+        } 
+        // Else wait the setSpecification call.
+    }
+
+    /**
+     * Set the specification of the current dependency.
+     * In order to store the id of the dependency, this
+     * method is override.
+     * @param spec : request service Class
+     * @see org.apache.felix.ipojo.util.DependencyModel#setSpecification(java.lang.Class)
+     */
+    public void setSpecification(Class spec) {
+        super.setSpecification(spec);
+        if (m_id == null) {
+            m_id = spec.getName();
         }
     }
 
@@ -235,122 +145,76 @@
         return m_field;
     }
 
-
-    public String getSpecification() {
-        return m_specification;
-    }
-
-
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
-
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-
-    /**
-     * Set the dependency to aggregate.
-     */
-    protected void setAggregate() {
-        m_isAggregate = true;
-    }
-    
-    /**
-     * Activate the dependency.
-     * For static policy it freezes the service reference set.
-     */
-    void activate() {
-        if (m_bindingPolicy == STATIC_POLICY) {
-            m_activated = true;
-        }
-    }
-
-    /**
-     * Set the tracked specification for this dependency.
-     * @param spec : the tracked specification (interface name)
-     */
-    protected void setSpecification(String spec) {
-        m_specification = spec;
-    }
-
     /**
      * Add a callback to the dependency.
-     * @param cb : callback to add
+     * @param callback : callback to add
      */
-    protected void addDependencyCallback(DependencyCallback cb) {
-        if (m_callbacks.length > 0) {
+    protected void addDependencyCallback(DependencyCallback callback) {
+        if (m_callbacks == null) {
+            m_callbacks = new DependencyCallback[] { callback };
+        } else {
             DependencyCallback[] newCallbacks = new DependencyCallback[m_callbacks.length + 1];
             System.arraycopy(m_callbacks, 0, newCallbacks, 0, m_callbacks.length);
-            newCallbacks[m_callbacks.length] = cb;
+            newCallbacks[m_callbacks.length] = callback;
             m_callbacks = newCallbacks;
-        } else {
-            m_callbacks = new DependencyCallback[] { cb };
         }
     }
 
+    /**
+     * Stop the current dependency.
+     * @see org.apache.felix.ipojo.util.DependencyModel#stop()
+     */
+    public void stop() {
+        m_isStarted = false;
+        super.stop();
+    }
 
     /**
      * Get the string form of the filter.
      * @return : the string form of the filter.
      */
-    public String getFilter() {
-        if (m_strFilter == null) { return ""; }
-        return m_strFilter;
+    public String getStringFilter() {
+        return getFilter().toString();
     }
 
-
     public DependencyHandler getHandler() {
         return m_handler;
     }
 
-    /**
-     * Build the Set [service reference] of used services.
-     * @return the used service.
-     */
-    public List getUsedServices() {
-        return m_usedReferences;
+    public synchronized boolean isFrozen() {
+        return m_isFrozen;
     }
 
     /**
-     * This method is called by the replaced code in the component
-     * implementation class. Construct the service object list is necessary.
-     * 
-     * @return null or a service object or a list of service object according to
-     * the dependency.
+     * Call the bind method.
+     * @param pojo : pojo instance on which calling the bind method.
      */
-    Object get() {
-        // Initialize the thread local object is not already touched.
-        if (m_usage.getObjects().isEmpty()) {
-            if (isAggregate()) {
-                synchronized (m_tracker) {
-                    for (int i = 0; i < m_references.size(); i++) {
-                        ServiceReference ref = (ServiceReference) m_references.get(i);
-                        m_usage.getReferences().add(ref);
-                        m_usage.getObjects().add(getService(ref));
-                    }
-                }
-            } else {
-                if (m_references.size() == 0) {
-                    if (m_nullable == null) {
-                        m_handler.log(Logger.WARNING, "[" + m_handler.getInstanceManager().getInstanceName() + "] The dependency is not optional, however no service object can be injected in " + m_field + " -> " + m_specification);
-                        return null;
-                    }
-                    m_usage.getObjects().add(m_nullable);
-                } else {
-                    ServiceReference ref = (ServiceReference) m_references.get(0);
-                    m_usage.getReferences().add(ref); // Get the first one
-                    m_usage.getObjects().add(getService(ref));
-                }
-            }
-            m_usage.setStackLevel(1);
+    protected synchronized void onObjectCreation(Object pojo) {
+        if (!m_isStarted) { return; }
+
+        // We are notified of an instance creation, we have to freeze when the static policy is used
+        if (getBindingPolicy() == STATIC_BINDING_POLICY) {
+            m_isFrozen = true;
         }
 
-        if (m_isAggregate) { // Multiple dependency
-            return (Object[]) m_usage.getObjects().toArray((Object[]) Array.newInstance(m_clazz, m_usage.getObjects().size()));
-        } else {
-            return m_usage.getObjects().get(0);
+        // Check optional case : nullable object case : do not call bind on nullable object
+        if (isOptional() && getSize() == 0) { return; }
+
+        // Call bind callback.
+        for (int j = 0; m_callbacks != null && j < m_callbacks.length; j++) {
+            if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
+                if (isAggregate()) {
+                    ServiceReference[] refs = getServiceReferences();
+                    for (int i = 0; i < refs.length; i++) {
+                        invokeCallback(m_callbacks[j], refs[i], pojo);
+                    }
+                } else {
+                    ServiceReference ref = getServiceReference();
+                    if (ref != null) {
+                        invokeCallback(m_callbacks[j], ref, pojo);
+                    }
+                }
+            }
         }
     }
 
@@ -360,95 +224,38 @@
      */
     private void callUnbindMethod(ServiceReference ref) {
         if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
-            for (int i = 0; i < m_callbacks.length; i++) {
+            for (int i = 0; m_callbacks != null && 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.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (IllegalAccessException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (InvocationTargetException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-                        m_handler.getInstanceManager().stop();
-                    }
+                    invokeCallback(m_callbacks[i], ref, null); // Call on each created pojo objects.
                 }
             }
         }
     }
 
     /**
-     * Get a service object for the given reference according to the resolving policy.
-     * @param ref : service reference
-     * @return the service object
+     * Helper method calling the given callback.
+     * @param callback : callback to call.
+     * @param ref : service reference.
+     * @param pojo : pojo on which calling the callback, if null call on each created pojo objects.
      */
-    private synchronized Object getService(ServiceReference ref) {
-        if (!m_usedReferences.contains(ref)) {
-            m_usedReferences.add(ref);
-        }
-        return m_tracker.getService(ref);
-    }
-    
-    /**
-     * Unget the given service reference according to the resolving policy.
-     * @param ref : service reference to unget
-     */
-    private void ungetService(ServiceReference ref) {
-        m_tracker.ungetService(ref);
-    }
-
-    /**
-     * Call the bind method.
-     * @param instance : instance on which calling the bind method.
-     */
-    protected synchronized 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.size() == 0) { return; }
-
-        if (m_isAggregate) {
-            for (int i = 0; i < m_references.size(); i++) {
-                ServiceReference ref = (ServiceReference) m_references.get(i);
-                for (int j = 0; j < m_callbacks.length; j++) {
-                    if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
-                        try {
-                            m_callbacks[j].callOnInstance(instance, ref, getService(ref));
-                        } catch (NoSuchMethodException e) {
-                            m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-                            m_handler.getInstanceManager().stop();
-                        } catch (IllegalAccessException e) {
-                            m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-                            m_handler.getInstanceManager().stop();
-                        } catch (InvocationTargetException e) {
-                            m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-                            m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-                        }
-                    }
-                }
+    private void invokeCallback(DependencyCallback callback, ServiceReference ref, Object pojo) {
+        try {
+            if (pojo == null) {
+                callback.call(ref, getService(ref));
+            } else {
+                callback.callOnInstance(pojo, ref, getService(ref));
             }
-        } else {
-            for (int j = 0; j < m_callbacks.length; j++) {
-                if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
-                    try {
-                        ServiceReference ref = (ServiceReference) m_references.get(0);
-                        if (ref != null) {
-                            m_callbacks[j].callOnInstance(instance, ref, getService(ref));
-                        }
-                    } catch (NoSuchMethodException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (IllegalAccessException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (InvocationTargetException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-                        m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-                    }
-                }
-            }
+        } catch (NoSuchMethodException e) {
+            m_handler.error("The method " + callback.getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
+            m_handler.getInstanceManager().stop();
+        } catch (IllegalAccessException e) {
+            m_handler.error("The method " + callback.getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
+            m_handler.getInstanceManager().stop();
+        } catch (InvocationTargetException e) {
+            m_handler.error("The method " + callback.getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + " throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());
+            m_handler.getInstanceManager().stop();
         }
+
     }
 
     /**
@@ -459,112 +266,45 @@
         // call bind method :
         // if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
         if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
-            for (int i = 0; i < m_callbacks.length; i++) {
+            for (int i = 0; m_callbacks != null && i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.BIND) {
-                    try {
-                        m_callbacks[i].call(ref, getService(ref));
-                        ungetService(ref);
-                    } catch (NoSuchMethodException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (IllegalAccessException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (InvocationTargetException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-                        m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-                    }
+                    invokeCallback(m_callbacks[i], ref, null);
                 }
             }
         }
     }
-
+    
     /**
      * Start the dependency.
      */
-    public void start() {
-        
-        m_serviceContext = new PolicyServiceContext(m_handler.getInstanceManager().getGlobalContext(), m_handler.getInstanceManager().getLocalServiceContext(), m_policy);
-        
-        // Construct the filter with the objectclass + filter
-        String filter = "(objectClass=" + m_specification + ")";
-        if (m_strFilter != null) {
-            filter = "(&" + filter + m_strFilter + ")";
-        }
-        
-        try {
-            m_clazz = m_handler.getInstanceManager().getContext().getBundle().loadClass(m_specification);
-        } catch (ClassNotFoundException e) {
-            m_handler.log(Logger.ERROR, "Cannot load the interface class for the dependency " + m_field + " [" + m_specification + "]");
-        }
-        
-        if (m_isOptional) {
-            if (m_di != null) {
-                try {
-                    Class c = getHandler().getInstanceManager().getContext().getBundle().loadClass(m_di);
-                    m_nullable = c.newInstance();
-                } catch (IllegalAccessException e) {
-                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + m_di + " : " + e.getMessage());
-                } catch (InstantiationException e) {
-                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + m_di + " : " + e.getMessage());
-                } catch (ClassNotFoundException e) {
-                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + m_di + " : " + e.getMessage());
-                }
+    public void start() {        
+        if (isOptional() && !isAggregate()) {
+            if (m_di == null) {
+                // To load the proxy we use the POJO class loader. Indeed, this classloader imports iPOJO (so can access to Nullable) and has access to the service specification.
+                m_nullable = Proxy.newProxyInstance(getHandler().getInstanceManager().getClazz().getClassLoader(), new Class[] { getSpecification(), Nullable.class }, new NullableObject()); // NOPMD
             } else {
-                m_nullable = Proxy.newProxyInstance(getHandler().getInstanceManager().getClazz().getClassLoader(), new Class[] {m_clazz, Nullable.class}, new NullableObject());
+                try {
+                    Class clazz = getHandler().getInstanceManager().getContext().getBundle().loadClass(m_di);
+                    m_nullable = clazz.newInstance();
+                } catch (IllegalAccessException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                } catch (InstantiationException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                }
             }
         }
 
-        m_state = UNRESOLVED;
+        super.start();
 
-        try {
-            m_filter = m_handler.getInstanceManager().getContext().createFilter(filter); // Store the filter
-        } catch (InvalidSyntaxException e1) {
-            m_handler.log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] A filter is malformed : " + filter + " - " + e1.getMessage());
-            m_handler.getInstanceManager().stop();
-        }  
-        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;
-        }
-    }
-
-    /**
-     * Stop the dependency.
-     */
-    public void stop() {
-        if (m_tracker != null) {
-            m_tracker.close(); // Will unget all used reference.
-            m_tracker = null;
+        if (getBindingPolicy() == STATIC_BINDING_POLICY && m_handler.getInstanceManager().getPojoObjects() != null) {
+            m_isFrozen = true;
         }
 
-        m_state = UNRESOLVED;
-
-        m_activated = false;
-        m_references.clear();
-        m_usedReferences.clear();
-        m_clazz = null;
+        m_isStarted = true;
     }
 
-    /**
-     * Return the state of the dependency.
-     * @return the state of the dependency (1 : valid, 2 : invalid)
-     */
-    public int getState() {
-        return m_state;
-    }
-
-    /**
-     * Return the list of used service reference.
-     * @return the service reference list.
-     */
-    public List getServiceReferences() {
-        return m_references;
-    }
-    
     protected DependencyCallback[] getCallbacks() {
         return m_callbacks;
     }
@@ -572,136 +312,183 @@
     /**
      * Set that this dependency is a service level dependency.
      * This forces the scoping policy to be STRICT. 
-     * @param b
      */
     public void setServiceLevelDependency() {
         m_isServiceLevelRequirement = true;
-        m_policy = PolicyServiceContext.LOCAL;
+        setBundleContext(new PolicyServiceContext(m_handler.getInstanceManager().getGlobalContext(), m_handler.getInstanceManager().getLocalServiceContext(), PolicyServiceContext.LOCAL));
     }
 
     public String getId() {
         return m_id;
     }
-    
+
     public boolean isServiceLevelRequirement() {
         return m_isServiceLevelRequirement;
     }
 
-    /**
-     * Method called when a thread enters in a method.
-     * @param method : method id.
-     */
-    public void entry(String method) {
-        if (! m_usage.getObjects().isEmpty()) {
-            int level = m_usage.getStackLevel();
-            m_usage.setStackLevel(level++);
-        }
-    }
-    
-    /**
-     * Method called when a thread exits a method.
-     * @param method : the method id.
-     */
-    public void exit(String method) {
-        if (! m_usage.getObjects().isEmpty()) {
-            int level = m_usage.getStackLevel();
-            level = level - 1;
-            if (level == 0) {
-                // Exit the method flow => Release all object
-                m_usage.getObjects().clear();
-                List refs = m_usage.getReferences();
-                refs.clear();
-            }
-        }
-    }
 
-   /**
-    * 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_activated) {
-            return true;
-        }
-        return false;
-    }
-    
     /**
-     * A new service reference has been added in the tracker.
-     * Call the bind method if needed, and check the dependency context.
-     * @param reference : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     * A new service has to be injected.
+     * @param reference : the new matching service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceArrival(org.osgi.framework.ServiceReference)
      */
-    public void addedService(ServiceReference reference) {
-        m_references.add(reference);
-        if (m_bindingPolicy == DYNAMIC_PRIORITY_POLICY) {
-            Collections.sort(m_references, new ServiceReferenceRankingComparator());
-        }
-        m_state = RESOLVED;
-        if (m_isAggregate || m_references.size() == 1) {
-            callBindMethod(reference);
-        }
-        
-        m_handler.checkContext();
+    public void onServiceArrival(ServiceReference reference) {
+        callBindMethod(reference);
+        //The method is only called when a new service arrives, or when the used one is replaced.
     }
 
     /**
-     * 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)
+     * A used (already injected) service disappears.
+     * @param ref : leaving service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceDeparture(org.osgi.framework.ServiceReference)
      */
-    public void modifiedService(ServiceReference ref, Object arg1) { }
+    public void onServiceDeparture(ServiceReference ref) {
+        callUnbindMethod(ref);
+    }
 
     /**
-     * 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)
+     * The dependency has been reconfigured.
+     * @param departs : service no more matching.
+     * @param arrivals : new services
+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
      */
-    public void removedService(ServiceReference ref, Object arg1) {
-        // Call unbind method
-        boolean hasChanged = false;
-        m_references.remove(ref);
-        if (m_usedReferences.remove(ref)) {
-            callUnbindMethod(ref);
-            
-            // Null the ref in the instance manager map
-            if (m_field != null) {
-                m_handler.getInstanceManager().setterCallback(m_field, null);
-            }
-            
-            // Unget the service reference
-            ungetService(ref);
-            hasChanged = true;
-        }
-        
-        if (m_bindingPolicy == STATIC_POLICY) {
-            if (hasChanged && m_activated) {
-                m_state = BROKEN;
-            }
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        throw new UnsupportedOperationException("Dependency set change is not yet supported");
+    }
+
+    /**
+     * Get the used service references list.
+     * @return the used service reference or null if no service reference are available.
+     */
+    public List getServiceReferencesAsList() {
+        ServiceReference[] refs = super.getServiceReferences();
+        if (refs == null) {
+            return null;
         } else {
-            // Is the state valid or invalid, the reference is already removed
-            if (m_references.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_references.size() != 0) {
-                        callBindMethod(m_references.get(0));
+            return Arrays.asList(refs);
+        }
+    }
+
+    /**
+     * This method is called by the replaced code in the component
+     * implementation class. Construct the service object list is necessary.
+     * @param pojo : POJO object.
+     * @param fieldName : field
+     * @param value : last value.
+     * @return the service object or a nullable / default implementation if defined.
+     * @see org.apache.felix.ipojo.FieldInterceptor#onGet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public Object onGet(Object pojo, String fieldName, Object value) {
+     // Initialize the thread local object is not already touched.
+        Usage usage = (Usage) m_usage.get();
+        if (usage.m_stack == 0) { // uninitialized usage.
+            ServiceReference[] refs = super.getServiceReferences();
+            if (isAggregate()) { // If we are aggregate we get the objects.
+                if (refs == null) {
+                    usage.m_objects = (Object[]) Array.newInstance(getSpecification(), 0); // Create an empty array.
+                } else {
+                   // Use a reflective construction to avoid class cast exception. This method allow to set the component type.
+                    usage.m_objects = (Object[]) Array.newInstance(getSpecification(), refs.length); 
+                    for (int i = 0; refs != null && i < refs.length; i++) {
+                        ServiceReference ref = refs[i];
+                        usage.m_objects[i] = getService(ref);
                     }
                 }
+            } else { // We are singular.
+                // Use a reflective construction to avoid class cast exception. This method allow to set the component type.
+                usage.m_objects = (Object[]) Array.newInstance(getSpecification(), 1);
+                if (refs == null) {
+                    if (m_nullable == null) {
+                        m_handler.warn("[" + m_handler.getInstanceManager().getInstanceName() + "] The dependency is not optional, however no service object can be injected in " + m_field + " -> " + getSpecification().getName());
+                        return null;
+                    }
+                    usage.m_objects[0] = m_nullable;
+                } else {
+                    ServiceReference ref = getServiceReference();
+                    usage.m_objects[0] = getService(ref);
+                }
+            }
+            usage.inc(); // Start the tracking, so fix the stack level to 1
+            m_usage.set(usage);
+        }
+
+        if (isAggregate()) { // Multiple dependency
+            return usage.m_objects;
+        } else {
+            return usage.m_objects[0];
+        }
+    }
+
+    /**
+     * The field was set.
+     * This method should not be call if the POJO is written correctly.
+     * @param pojo : POJO object
+     * @param fieldName : field name
+     * @param value : set value.
+     * @see org.apache.felix.ipojo.FieldInterceptor#onSet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public void onSet(Object pojo, String fieldName, Object value) {
+        // Nothing to do.
+    }
+
+    /**
+     * A POJO method will be invoked.
+     * @param pojo : Pojo object
+     * @param method : called method
+     * @param args : arguments
+     * @see org.apache.felix.ipojo.MethodInterceptor#onEntry(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public void onEntry(Object pojo, Method method, Object[] args) {
+        if (m_usage != null) {
+            Usage usage = (Usage) m_usage.get();
+            if (usage.m_stack > 0) {
+                usage.inc();
+                m_usage.set(usage); // Set the Thread local as value has been modified
+            }
+        }
+    }
+
+    /**
+     * A POJO method has thrown an error.
+     * This method does nothing and wait for the finally.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @param throwable : thrown error
+     * @see org.apache.felix.ipojo.MethodInterceptor#onError(java.lang.Object, java.lang.reflect.Method, java.lang.Throwable)
+     */
+    public void onError(Object pojo, Method method, Throwable throwable) {
+        // Nothing to do  : wait onFinally
+    }
+
+    /**
+     * A POJO method has returned.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @param returnedObj : returned object (null for void method)
+     * @see org.apache.felix.ipojo.MethodInterceptor#onExit(java.lang.Object, java.lang.reflect.Method, java.lang.Object)
+     */
+    public void onExit(Object pojo, Method method, Object returnedObj) {
+        // Nothing to do  : wait onFinally
+        
+    }
+
+    /**
+     * A POJO method is finished.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @see org.apache.felix.ipojo.MethodInterceptor#onFinally(java.lang.Object, java.lang.reflect.Method)
+     */
+    public void onFinally(Object pojo, Method method) {
+        if (m_usage != null) {
+            Usage usage = (Usage) m_usage.get();
+            if (usage.m_stack > 0) {
+                if (usage.dec()) {
+                    // Exit the method flow => Release all objects
+                    usage.clear();
+                    m_usage.set(usage); // Set the Thread local as value has been modified
+                }
             }
         }
-
-        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 cb47c30..ad476c6 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
@@ -22,7 +22,6 @@
 import java.lang.reflect.Method;
 
 import org.apache.felix.ipojo.util.Callback;
-import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -42,7 +41,6 @@
      * Unbind method (called when a service disappears).
      */
     public static final int UNBIND = 1;
-    
 
     /**
      * Is the method a bind method or an unbind method ?
@@ -104,20 +102,25 @@
     protected void searchMethod() {
         if (m_argument != null) {
             Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getDeclaredMethods();
-            for (int i = 0; m_methodObj == null && i < methods.length; i++) {
+            for (int i = 0; i < methods.length; i++) {
                 // First check the method name
                 if (methods[i].getName().equals(m_method)) {
                     // Check arguments
                     Class[] clazzes = methods[i].getParameterTypes();
-                    if (clazzes.length == m_argument.length) { // Test size to avoid useless loop
-                        boolean ok = true;
-                        for (int j = 0; ok && j < m_argument.length; j++) {
-                            if (!m_argument[j].equals(clazzes[j].getName())) {
-                                ok = false;
+                    if (clazzes.length == m_argument.length) { // Test size to avoid useless loop // NOPMD
+                        int argIndex = 0;
+                        for (; argIndex < m_argument.length; argIndex++) {
+                            if (!m_argument[argIndex].equals(clazzes[argIndex].getName())) {
+                                break;
                             }
                         }
-                        if (ok) {
+                        if (argIndex == m_argument.length) { // If the array was completely read.
                             m_methodObj = methods[i]; // It is the looked method.
+                            if (! m_methodObj.isAccessible()) { 
+                                // If not accessible, try to set the accessibility.
+                                m_methodObj.setAccessible(true);
+                            }
+                            return;
                         }
                     }
 
@@ -125,51 +128,64 @@
             }
         }
         
-        if (m_methodObj == null) { //look at parent classes
-            Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getMethods();
-            for (int i = 0; m_methodObj == null && i < methods.length; i++) {
-                // First check the method name
-                if (methods[i].getName().equals(m_method)) {
-                    // Check arguments
-                    Class[] clazzes = methods[i].getParameterTypes();
-                    switch(clazzes.length) {
-                        case 0 : 
-                            // Callback with no arguments.
-                            m_methodObj = methods[i];
-                            m_argument = new String[0];
-                            break;
-                        case 1 :
-                            if (clazzes[0].getName().equals(ServiceReference.class.getName())) {
-                                // Callback with a service reference.
-                                m_methodObj = methods[i];
-                                m_argument = new String[] {ServiceReference.class.getName()};
-                                break;
-                            }
-                            if (clazzes[0].getName().equals(m_dependency.getSpecification())) {
-                                // Callback with the service object.
-                                m_methodObj = methods[i];
-                                m_argument = new String[] {m_dependency.getSpecification()};
-                                break;
-                            }
-                        case 2 : 
-                            if (clazzes[0].getName().equals(m_dependency.getSpecification())  && clazzes[1].getName().equals(ServiceReference.class.getName())) {
-                                // Callback with two arguments.
-                                m_methodObj = methods[i];
-                                m_argument = new String[] {m_dependency.getSpecification(), ServiceReference.class.getName()};
-                            }
-                            break;
-                        default :
-                            break;
-                    }
-                }
-            }
-        }
+        // Not found => Try parent method.
+        searchParentMethod();
         
         if (m_methodObj == null) {
-            m_dependency.getHandler().log(Logger.ERROR, "The method " + m_method + " cannot be called : method not found");
+            // If not found, stop the instance (fatal error)
+            m_dependency.getHandler().error("The method " + m_method + " cannot be called : method not found");
             m_dependency.getHandler().getInstanceManager().stop();
         } else {
-            m_methodObj.setAccessible(true);
+            if (! m_methodObj.isAccessible()) { 
+                // If not accessible, try to set the accessibility.
+                m_methodObj.setAccessible(true);
+            }
+        }
+    }
+    
+    /**
+     * Introspect parent class to find the method.
+     */
+    private void searchParentMethod() {
+        // look at parent classes
+        Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            // First check the method name
+            if (methods[i].getName().equals(m_method)) {
+                // Check arguments
+                Class[] clazzes = methods[i].getParameterTypes();
+                switch (clazzes.length) {
+                    case 0:
+                        // Callback with no arguments.
+                        m_methodObj = methods[i];
+                        m_argument = new String[0];
+                        return;
+                    case 1:
+                        if (clazzes[0].getName().equals(ServiceReference.class.getName())) {
+                            // Callback with a service reference.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { ServiceReference.class.getName() };
+                            return;
+                        }
+                        if (clazzes[0].getName().equals(m_dependency.getSpecification().getName())) {
+                            // Callback with the service object.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { m_dependency.getSpecification().getName() };
+                            return;
+                        }
+                        break;
+                    case 2:
+                        if (clazzes[0].getName().equals(m_dependency.getSpecification().getName()) && clazzes[1].getName().equals(ServiceReference.class.getName())) {
+                            // Callback with two arguments.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { m_dependency.getSpecification().getName(), ServiceReference.class.getName() };
+                            return;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
         }
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
index f9dea1b..6c09bd5 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
@@ -79,7 +79,6 @@
         m_optional = optional;
         m_filter = filter;
         m_state = state;
-        m_serviceReferences = new ArrayList();
     }
 
     public boolean isMultiple() { return m_multiple; }
@@ -106,9 +105,9 @@
 
     /**
      * Set the service reference array.
-     * @param sr : the list of service reference
+     * @param refs : the list of service reference
      */
-    public void setServiceReferences(List sr) { m_serviceReferences = sr; }
+    public void setServiceReferences(List refs) { m_serviceReferences = refs; }
 
     /**
      * Get the used service set.
@@ -118,10 +117,10 @@
 
     /**
      * Set the usedServices.
-     * @param hm : the list of used service reference.
+     * @param usages : the list of used service reference.
      */
-    public void setUsedServices(List hm) {
-        m_usedServices = hm;
+    public void setUsedServices(List usages) {
+        m_usedServices = usages;
     }
 
 
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 433f0b1..5a0f4d8 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
@@ -18,27 +18,30 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.util.ArrayList;
+import java.util.Comparator;
 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.IPojoContext;
 import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.DependencyStateListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
 /**
  * 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 PrimitiveHandler {
+public class DependencyHandler extends PrimitiveHandler implements DependencyStateListener {
 
     /**
      * List of dependencies of the component.
@@ -46,12 +49,6 @@
     private Dependency[] m_dependencies = new Dependency[0];
 
     /**
-     * State of the handler.
-     * Lifecycle controller.
-     */
-    private boolean m_state;
-
-    /**
      * Is the handler started.
      */
     private boolean m_started;
@@ -61,16 +58,18 @@
      * @param dep : the dependency to add
      */
     private void addDependency(Dependency dep) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            if (m_dependencies[i] == dep) { return; }
+        for (int i = 0; m_dependencies != null && i < m_dependencies.length; i++) {
+            if (m_dependencies[i] == dep) {
+                return;
+            }
         }
-        if (m_dependencies.length > 0) {
+        if (m_dependencies == null) {
+            m_dependencies = new Dependency[] { dep };
+        } else {
             Dependency[] newDep = new Dependency[m_dependencies.length + 1];
             System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
             newDep[m_dependencies.length] = dep;
             m_dependencies = newDep;
-        } else {
-            m_dependencies = new Dependency[] { dep };
         }
     }
 
@@ -83,36 +82,56 @@
     }
 
     /**
+     * Validate method. This method is invoked by an AbstractServiceDependency when this dependency becomes RESOLVED.
+     * @param dep : the dependency becoming RESOLVED.
+     * @see org.apache.felix.ipojo.util.DependencyStateListener#validate(org.apache.felix.ipojo.util.DependencyModel)
+     */
+    public void validate(DependencyModel dep) {
+        checkContext();
+    }
+
+    /**
+     * Invalidate method. This method is invoked by an AbstractServiceDependency when this dependency becomes UNRESOLVED or BROKEN.
+     * @param dep : the dependency becoming UNRESOLVED or BROKEN.
+     * @see org.apache.felix.ipojo.util.DependencyStateListener#invalidate(org.apache.felix.ipojo.util.DependencyModel)
+     */
+    public void invalidate(DependencyModel dep) {
+        setValidity(false);
+    }
+
+    /**
      * Check the validity of the dependencies.
      */
     protected void checkContext() {
-        if (! m_started) { return; }
+        if (!m_started) {
+            return;
+        }
         synchronized (m_dependencies) {
             // Store the initial state
-            boolean initialState = m_state;
+            boolean initialState = getValidity();
 
             boolean valid = true;
             for (int i = 0; i < m_dependencies.length; i++) {
                 Dependency dep = m_dependencies[i];
-                if (dep.getState() > Dependency.RESOLVED) { 
+                if (dep.getState() != Dependency.RESOLVED) {
                     valid = false;
                     break;
                 }
             }
-            
+
             // Check the component dependencies
             if (valid) {
                 // The dependencies are valid
                 if (!initialState) {
                     // There is a state change
-                    m_state = true;
+                    setValidity(true);
                 }
                 // Else do nothing, the component state stay VALID
             } else {
                 // The dependencies are not valid
                 if (initialState) {
                     // There is a state change
-                    m_state = false;
+                    setValidity(false);
                 }
                 // Else do nothing, the component state stay UNRESOLVED
             }
@@ -121,155 +140,197 @@
     }
 
     /**
-     * Check if the dependency given is valid in the sense that metadata are
-     * consistent.
+     * 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) throws ConfigurationException {
+    private boolean checkDependency(Dependency dep, PojoMetadata 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++) {
+        if (callbacks == null && field == null) {
+            throw new ConfigurationException("A service requirement requires at least callbacks or a field");
+        }
+
+        for (int i = 0; callbacks != null && i < callbacks.length; i++) {
             MethodMetadata[] mets = manipulation.getMethods(callbacks[i].getMethodName());
-            if (mets.length != 0) {
+            if (mets.length == 0) {
+                info("A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation, try the super classes");
+            } else {
                 if (mets[0].getMethodArguments().length > 2) {
-                    throw new ConfigurationException("Requirement Callback : A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 or 2 arguments");
+                    throw new ConfigurationException("Requirement Callback : A requirement callback "
+                            + callbacks[i].getMethodName()
+                            + " must have 0 or 1 or 2 arguments");
                 }
-                
+
                 callbacks[i].setArgument(mets[0].getMethodArguments());
+
                 if (mets[0].getMethodArguments().length == 1) {
                     if (!mets[0].getMethodArguments()[0].equals(ServiceReference.class.getName())) {
-                        if (dep.getSpecification() == null) {
-                            dep.setSpecification(mets[0].getMethodArguments()[0]);
-                        }
-                        if (!dep.getSpecification().equals(mets[0].getMethodArguments()[0])) {
-                            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]);
-                        }
+                        // The callback receives the service object.
+                        setSpecification(dep, mets[0].getMethodArguments()[0], false); // Just warn if a mismatch is discovered.
                     }
                 } else if (mets[0].getMethodArguments().length == 2) {
-                    // Check that the second arguments is a service reference
+                    // The callback receives service object, service reference. Check that the second argument is a service reference
                     if (!mets[0].getMethodArguments()[1].equals(ServiceReference.class.getName())) {
-                        String message = "The requirement callback " + callbacks[i].getMethodName() + " must have a ServiceReference as the second arguments";
+                        String message =
+                                "The requirement callback " + callbacks[i].getMethodName() + " must have a ServiceReference as the second argument";
                         throw new ConfigurationException(message);
                     }
-                    if (dep.getSpecification() == null) {
-                        dep.setSpecification(mets[0].getMethodArguments()[0]);
-                    } else {
-                        if (!dep.getSpecification().equals(mets[0].getMethodArguments()[0])) {
-                            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]);
-                        }
-                    }
+                    setSpecification(dep, mets[0].getMethodArguments()[0], false); // Just warn if a mismatch is discovered.
                 }
-            } else {
-                log(Logger.INFO, "A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation, try the super classes");
             }
 
         }
 
         if (field != null) {
-            FieldMetadata fm = manipulation.getField(field);
-            if (fm == null) {
-                throw new ConfigurationException("Requirement Callback : A requirement field " + field + " does not exist in the implementation class");
+            FieldMetadata meta = manipulation.getField(field);
+            if (meta == null) {
+                throw new ConfigurationException("Requirement Callback : A requirement field "
+                        + field
+                        + " does not exist in the implementation class");
             }
-            String type = fm.getFieldType();
+            String type = meta.getFieldType();
             if (type.endsWith("[]")) {
                 // Set the dependency to multiple
-                dep.setAggregate();
+                dep.setAggregate(true);
                 type = type.substring(0, type.length() - 2);
+            } else {
+                if (dep.isAggregate()) {
+                    throw new ConfigurationException("A required service is not correct : the field "
+                            + meta.getFieldName()
+                            + " must be an array to support aggregate injections");
+                }
             }
-
-            if (dep.getSpecification() == null) {
-                dep.setSpecification(type);
-            }
-
-            if (!dep.getSpecification().equals(type)) {
-                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);
-            }
+            setSpecification(dep, type, true); // Throw an exception if the filed type mismatch.
         }
 
-        //Check that all required info are set
+        // Check that all required info are set
         return dep.getSpecification() != null;
     }
 
     /**
+     * Check if we have to set the dependency specification with the given class name.
+     * @param dep : dependency to check
+     * @param className : class name
+     * @param error : set to true to throw an error if the set dependency specification and the given specification are different.
+     * @throws ConfigurationException : the specification class cannot be loaded correctly
+     */
+    private void setSpecification(Dependency dep, String className, boolean error) throws ConfigurationException {
+        // We have to set the dependency in two cases : either the dependency as no specification, or the specification is different from the given
+        // one
+        if (dep.getSpecification() == null || !dep.getSpecification().getName().equals(className)) {
+            if (dep.getSpecification() != null) {
+                if (error) {
+                    throw new ConfigurationException("A required service is not correct : the discoevered type ["
+                            + className
+                            + "] and the specified (or already discovered)  service interface ["
+                            + dep.getSpecification().getName()
+                            + "] are not the same");
+                } else {
+                    // If the specification is different, warn that we will overide it.
+                    warn("[DependencyHandler on "
+                            + getInstanceManager().getInstanceName()
+                            + "] The field type ["
+                            + className
+                            + "] and the needed service interface ["
+                            + dep.getSpecification()
+                            + "] are not the same");
+                }
+            }
+            try {
+                dep.setSpecification(getInstanceManager().getContext().getBundle().loadClass(className));
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("The required service interface cannot be loaded : " + e.getMessage());
+            }
+        }
+    }
+
+    /**
      * Configure the handler.
      * @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)
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element,
+     *      java.util.Dictionary)
      */
     public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
-        m_dependencies = new Dependency[0];
-
-        ManipulationMetadata manipulation = new ManipulationMetadata(componentMetadata);
-        List fl = new ArrayList();
+        // getPojoMetadata();
+        PojoMetadata manipulation = getFactory().getPojoMetadata();
+        boolean atLeastOneField = false;
 
         // Create the dependency according to the component metadata
         Element[] deps = componentMetadata.getElements("Requires");
-
+        
         // Get instance filters.
         Dictionary filtersConfiguration = (Dictionary) configuration.get("requires.filters");
-        
-        for (int i = 0; i < deps.length; i++) {
+
+        for (int i = 0; deps != null && i < deps.length; i++) {
             // Create the dependency metadata
             String field = deps[i].getAttribute("field");
             String serviceSpecification = deps[i].getAttribute("interface");
             String filter = deps[i].getAttribute("filter");
             String opt = deps[i].getAttribute("optional");
             boolean optional = opt != null && opt.equalsIgnoreCase("true");
-            String di = deps[i].getAttribute("default-implementation");
-            
+            String defaultImplem = deps[i].getAttribute("default-implementation");
+
             String agg = deps[i].getAttribute("aggregate");
             boolean aggregate = agg != null && agg.equalsIgnoreCase("true");
-            String id = deps[i].getAttribute("id");
+            String identitity = deps[i].getAttribute("id");
 
-            int scopePolicy = -1;
-            String scope = deps[i].getAttribute("scope"); 
+            String scope = deps[i].getAttribute("scope");
+            BundleContext context = getInstanceManager().getContext(); // Get the default bundle context.
             if (scope != null) {
-                if (scope.equalsIgnoreCase("global")) {
-                    scopePolicy = PolicyServiceContext.GLOBAL;
+                // If we are not in a composite, the policy is set to global.
+                if (scope.equalsIgnoreCase("global") || ((((IPojoContext) getInstanceManager().getContext()).getServiceContext()) == null)) {
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.GLOBAL);
                 } else if (scope.equalsIgnoreCase("composite")) {
-                    scopePolicy = PolicyServiceContext.LOCAL;
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.LOCAL);
                 } else if (scope.equalsIgnoreCase("composite+global")) {
-                    scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.LOCAL_AND_GLOBAL);
                 }
             }
 
             // Get instance filter if available
-            if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
-                filter = (String) filtersConfiguration.get(id);
+            if (filtersConfiguration != null && identitity != null && filtersConfiguration.get(identitity) != null) {
+                filter = (String) filtersConfiguration.get(identitity);
             }
-            
-            
-            // Parse binding policy
-            int bindingPolicy = Dependency.DYNAMIC_POLICY;
-            String policy = deps[i].getAttribute("policy"); 
-            if (policy != null) {
-                if (policy.equalsIgnoreCase("static")) {
-                    bindingPolicy = Dependency.STATIC_POLICY;
-                } else if (policy.equalsIgnoreCase("dynamic")) {
-                    bindingPolicy = Dependency.DYNAMIC_POLICY;
-                } else if (policy.equalsIgnoreCase("dynamic-priority")) {
-                    bindingPolicy = Dependency.DYNAMIC_PRIORITY_POLICY;
+
+            Filter fil = null;
+            if (filter != null) {
+                try {
+                    fil = getInstanceManager().getContext().createFilter(filter);
+                } catch (InvalidSyntaxException e) {
+                    throw new ConfigurationException("A requirement filter is invalid : " + filter + " - " + e.getMessage());
                 }
             }
-            
-            Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate, id, scopePolicy, bindingPolicy, di);
+
+            Class spec = null;
+            if (serviceSpecification != null) {
+                spec = DependencyModel.loadSpecification(serviceSpecification, getInstanceManager().getContext());
+            }
+
+            int policy = DependencyModel.getPolicy(deps[i]);
+            Comparator cmp = DependencyModel.getComparator(deps[i], getInstanceManager().getGlobalContext());
+            Dependency dep = new Dependency(this, field, spec, fil, optional, aggregate, identitity, context, policy, cmp, defaultImplem);
 
             // 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"); 
+            Element[] cbs = deps[i].getElements("Callback");
+            for (int j = 0; cbs != null && j < cbs.length; j++) {
+                if (!cbs[j].containsAttribute("method") && cbs[j].containsAttribute("type")) {
+                    throw new ConfigurationException("Requirement Callback : a dependency callback must contain a method and a type attribute");
                 }
-                String method = deps[i].getElements("Callback", "")[j].getAttribute("method");
-                String type = deps[i].getElements("Callback", "")[j].getAttribute("type");
+                String method = cbs[j].getAttribute("method");
+                String type = cbs[j].getAttribute("type");
                 int methodType = 0;
                 if ("bind".equalsIgnoreCase(type)) {
                     methodType = DependencyCallback.BIND;
@@ -277,74 +338,49 @@
                     methodType = DependencyCallback.UNBIND;
                 }
 
-                DependencyCallback dc = new DependencyCallback(dep, method, methodType);
-                dep.addDependencyCallback(dc);
+                DependencyCallback callback = new DependencyCallback(dep, method, methodType);
+                dep.addDependencyCallback(callback);
             }
 
             // Check the dependency :
             if (checkDependency(dep, manipulation)) {
                 addDependency(dep);
                 if (dep.getField() != null) {
-                    fl.add(manipulation.getField(dep.getField()));
+                    getInstanceManager().register(manipulation.getField(dep.getField()), dep);
+                    atLeastOneField = true;
                 }
             }
         }
 
-        if (deps.length > 0) {
-            getInstanceManager().register(this, (FieldMetadata[]) fl.toArray(new FieldMetadata[0]), manipulation.getMethods());
-        } else {
-            throw new ConfigurationException("No dependencies found in " + getInstanceManager().getInstanceName());
-        }
-    }
-
-    /**
-     * GetterCallback Method.
-     * @param fieldName : the field name.
-     * @param value : the value passed to the field (by the previous handler).
-     * @return the object that the dependency handler want to push.
-     * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
-     */
-    public Object getterCallback(String fieldName, Object value) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            String field = dep.getField();
-            if (field != null && field.equals(fieldName)) {
-                // The field name is a dependency, return the get
-                return dep.get();
-            }
-        }
-        // Else return the value
-        return value;
-    }
-
-    /**
-     * Method Entry callback.
-     * @param methodId : method Id.
-     * @see org.apache.felix.ipojo.Handler#entryCallback(java.lang.String)
-     */
-    public void entryCallback(String methodId) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            if (dep.getField() != null) {
-                dep.entry(methodId);
+        if (atLeastOneField) { // Does register only if we have fields
+            MethodMetadata[] methods = manipulation.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                for (int j = 0; j < m_dependencies.length; j++) {
+                    getInstanceManager().register(methods[i], m_dependencies[j]);
+                }
             }
         }
     }
 
-    /**
-     * Method Exit callback.
-     * @param methodId : method id.
-     * @param returnedObj : returned object.
-     * @see org.apache.felix.ipojo.Handler#exitCallback(java.lang.String, java.lang.Object)
-     */
-    public void exitCallback(String methodId, Object returnedObj) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            if (dep.getField() != null) {
-                dep.exit(methodId);
-            }
-        }
-    }
+//    /**
+//     * GetterCallback Method.
+//     * @param pojo : the pojo object on which the field is accessed
+//     * @param fieldName : the field name.
+//     * @param value : the value passed to the field (by the previous handler).
+//     * @return the object that the dependency handler want to push.
+//     * @see org.apache.felix.ipojo.Handler#onGet(Object, java.lang.String, java.lang.Object)
+//     */
+//    public Object onGet(Object pojo, String fieldName, Object value) {
+//        for (int i = 0; i < m_dependencies.length; i++) {
+//            Dependency dep = m_dependencies[i];
+//            if (fieldName.equals(dep.getField())) {
+//                // The field name is a dependency, return the get
+//                return dep.get();
+//            }
+//        }
+//        // Else return the value
+//        return value;
+//    }
 
     /**
      * Handler start method.
@@ -358,6 +394,7 @@
         }
         // Check the state
         m_started = true;
+        setValidity(false);
         checkContext();
     }
 
@@ -373,27 +410,13 @@
     }
 
     /**
-     * Handler createInstance method.
-     * This method is override to allow delayed callback invocation.
+     * Handler createInstance method. This method is override to allow delayed callback invocation.
      * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)
      */
-    public void objectCreated(Object instance) {
+    public void onCreation(Object instance) {
         for (int i = 0; i < m_dependencies.length; i++) {
-            m_dependencies[i].callBindMethod(instance);
-        }
-    }
-    
-    /**
-     * The instance state changes. If the new state is valid, we need to activate dependencies.
-     * @param state : the new state
-     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
-     */
-    public void stateChanged(int state) {
-        if (state == ComponentInstance.VALID) {
-            for (int i = 0; i < m_dependencies.length; i++) {
-                m_dependencies[i].activate();
-            }
+            m_dependencies[i].onObjectCreation(instance);
         }
     }
 
@@ -407,10 +430,11 @@
         for (int j = 0; j < getDependencies().length; j++) {
             Dependency dep = getDependencies()[j];
             // Create & add the dependency description
-            DependencyDescription dd = new DependencyDescription(dep.getSpecification(), dep.isAggregate(), dep.isOptional(), dep.getFilter(), dep.getState());
-            dd.setServiceReferences(dep.getServiceReferences());
-            dd.setUsedServices(dep.getUsedServices());
-            dhd.addDependency(dd);
+            DependencyDescription desc =
+                    new DependencyDescription(dep.getSpecification().getName(), dep.isAggregate(), dep.isOptional(), dep.getFilter(), dep.getState());
+            desc.setServiceReferences(dep.getServiceReferencesAsList());
+            desc.setUsedServices(dep.getUsedServiceReferences());
+            dhd.addDependency(desc);
         }
         return dhd;
     }
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 1615521..aaf5baa 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
@@ -42,10 +42,10 @@
 
     /**
      * Constructor.
-     * @param h : Handler.
+     * @param handler : Handler.
      */
-    public DependencyHandlerDescription(Handler h) {
-        super(h);
+    public DependencyHandlerDescription(Handler handler) {
+        super(handler);
     }
 
     /**
@@ -94,7 +94,7 @@
             Element dep = new Element("Requires", "");
             dep.addAttribute(new Attribute("Specification", m_dependencies[i].getInterface()));
             
-            if (!"".equals(m_dependencies[i].getFilter())) {
+            if (m_dependencies[i].getFilter() != null) {
                 dep.addAttribute(new Attribute("Filter", m_dependencies[i].getFilter()));
             }
             
@@ -112,16 +112,18 @@
             
             dep.addAttribute(new Attribute("State", state));
             List set = m_dependencies[i].getUsedServices();
-            Iterator it = set.iterator();
-            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 in = (String) ref.getProperty("instance.name");
-                if (in != null) {
-                    use.addAttribute(new Attribute("instance.name", in));
+            if (set != null) {
+                Iterator iterator = set.iterator();
+                while (iterator.hasNext()) {
+                    Element use = new Element("Uses", "");
+                    ServiceReference ref = (ServiceReference) iterator.next();
+                    use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString()));                
+                    String instance = (String) ref.getProperty("instance.name");
+                    if (instance != null) {
+                        use.addAttribute(new Attribute("instance.name", instance));
+                    }
+                    dep.addElement(use);
                 }
-                dep.addElement(use);
             }
             
             deps.addElement(dep);
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
index e0e4900..b11419f 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
@@ -26,41 +26,42 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class NullableObject implements InvocationHandler {
-    
+
     /**
      * Default boolean value.
      */
     private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;
+
     /**
      * Default byte value.
      */
     private static final Byte DEFAULT_BYTE = new Byte((byte) 0);
-    
+
     /**
      * Default short value.
      */
     private static final Short DEFAULT_SHORT = new Short((short) 0);
-    
+
     /**
      * Default integer value.
      */
     private static final Integer DEFAULT_INT = new Integer(0);
-    
+
     /**
      * Default long value.
      */
     private static final Long DEFAULT_LONG = new Long(0);
-    
+
     /**
      * Default float value.
      */
     private static final Float DEFAULT_FLOAT = new Float(0.0f);
-    
+
     /**
      * Default double value.
      */
     private static final Double DEFAULT_DOUBLE = new Double(0.0);
-    
+
     /**
      * Invokes a method on this null object. The method will return a default
      * value without doing anything.
@@ -72,19 +73,19 @@
      */
     public Object invoke(Object proxy, Method method, Object[] args) {
         Class returnType = method.getReturnType();
-        if (returnType.equals(Boolean.TYPE)) {
+        if (Boolean.TYPE.equals(returnType)) {
             return DEFAULT_BOOLEAN;
-        } else if (returnType.equals(Byte.TYPE)) {
+        } else if (Byte.TYPE.equals(returnType)) {
             return DEFAULT_BYTE;
-        } else if (returnType.equals(Short.TYPE)) {
+        } else if (Short.TYPE.equals(returnType)) {
             return DEFAULT_SHORT;
-        } else if (returnType.equals(Integer.TYPE)) {
+        } else if (Integer.TYPE.equals(returnType)) {
             return DEFAULT_INT;
-        } else if (returnType.equals(Long.TYPE)) {
+        } else if (Long.TYPE.equals(returnType)) {
             return DEFAULT_LONG;
-        } else if (returnType.equals(Float.TYPE)) {
+        } else if (Float.TYPE.equals(returnType)) {
             return DEFAULT_FLOAT;
-        } else if (returnType.equals(Double.TYPE)) {
+        } else if (Double.TYPE.equals(returnType)) {
             return DEFAULT_DOUBLE;
         } else {
             return null;
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
index 822910b..7d289f1 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
@@ -18,8 +18,6 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Object managing thread local copy of required services.
@@ -31,19 +29,40 @@
     /**
      * Structure contained in the Thread Local.
      */
-    private class Usage {
+    public class Usage {
+        
         /**
          * Stack Size.
          */
-        Integer m_stack = new Integer(0);
-        /**
-         * List of used service references.
-         */
-        List m_refs = new ArrayList();
+        int m_stack = 0;
         /**
          * List of used objects.
          */
-        List m_objects = new ArrayList();
+        Object[] m_objects;
+        
+        /**
+         * Increment the statck level.
+         */
+        public void inc() {
+            m_stack++;
+        }
+        
+        /**
+         * Decrement the stack level.
+         * @return  true if the stack is 0 after the decrement.
+         */
+        public boolean dec() {
+            m_stack--;
+            return m_stack == 0;
+        }
+        
+        /**
+         * Clear the service object array.
+         */
+        public void clear() {
+            m_objects = null;
+        }
+        
     }
     
     /**
@@ -53,45 +72,6 @@
      */
     public Object initialValue() {
         return new Usage();
-    }
-    
-    /**
-     * Get the list of stored references.
-     * @return the list of stored references.
-     */
-    public List getReferences() {
-        Usage use = (Usage) super.get();
-        return use.m_refs;
-    }
-    
-    /**
-     * Get the lost of stored object.
-     * @return the list of stored service objects.
-     */
-    public List getObjects() {
-        Usage use = (Usage) super.get();
-        return use.m_objects;
-    }
-    
-    /**
-     * Get the stack level.
-     * @return the stack level.
-     */
-    public int getStackLevel() {
-        Usage use = (Usage) super.get();
-        return use.m_stack.intValue();
-    }
-    
-    /**
-     * Set the stack level.
-     * @param level : the new stack level.
-     */
-    public void setStackLevel(int level) {
-        Usage use = (Usage) super.get();
-        use.m_stack = new Integer(level);
-    }
-    
-    
-    
+    }   
 
 }
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 15db443..cd86798 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
@@ -53,29 +53,29 @@
     /**
      * LifecycleCallback constructor.
      * 
-     * @param hh : the callback handler calling the callback
+     * @param handler : the callback handler calling the callback
      * @param transition : transition on which calling the callback
-     * @param mm : method metadata to invoke
+     * @param method : method metadata to invoke
      */
-    public LifecycleCallback(LifecycleCallbackHandler hh, int transition, MethodMetadata mm) {
+    public LifecycleCallback(LifecycleCallbackHandler handler, int transition, MethodMetadata method) {
         m_transition = transition;
-        m_callback = new Callback(mm, hh.getInstanceManager());
+        m_callback = new Callback(method, handler.getInstanceManager());
     }
     
     /**
      * LifecycleCallback constructor.
      * 
-     * @param hh : the callback handler calling the callback
+     * @param handler : the callback handler calling the callback
      * @param transition : transition on which calling the callback
-     * @param mm : method name to invoke
+     * @param method : method name to invoke
      */
-    public LifecycleCallback(LifecycleCallbackHandler hh, int transition, String mm) {
+    public LifecycleCallback(LifecycleCallbackHandler handler, int transition, String method) {
         m_transition = transition;
-        m_callback = new Callback(mm, new String[0], false, hh.getInstanceManager());
+        m_callback = new Callback(method, new String[0], false, handler.getInstanceManager());
     }
 
     /**
-     * Call the callback method when the transition from inital to final state is
+     * Call the callback method when the transition from inital tostate is
      * detected.
      * 
      * @throws NoSuchMethodException : Method is not found in the class
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 7b153ef..85ca69a 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
@@ -26,9 +26,8 @@
 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;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.parser.PojoMetadata;
 
 /**
  * Lifecycle callback handler.
@@ -54,11 +53,11 @@
     /**
      * Add the given callback to the callback list.
      * 
-     * @param hk : the element to add
+     * @param callback : the element to add
      */
-    private void addCallback(LifecycleCallback hk) {
+    private void addCallback(LifecycleCallback callback) {
         for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
-            if (m_callbacks[i] == hk) {
+            if (m_callbacks[i] == callback) {
                 return;
             }
         }
@@ -66,10 +65,10 @@
         if (m_callbacks.length > 0) {
             LifecycleCallback[] newHk = new LifecycleCallback[m_callbacks.length + 1];
             System.arraycopy(m_callbacks, 0, newHk, 0, m_callbacks.length);
-            newHk[m_callbacks.length] = hk;
+            newHk[m_callbacks.length] = callback;
             m_callbacks = newHk;
         } else {
-            m_callbacks = new LifecycleCallback[] { hk };
+            m_callbacks = new LifecycleCallback[] { callback };
         }
 
     }
@@ -87,38 +86,38 @@
         String imm = metadata.getAttribute("immediate");
         m_immediate = imm != null && imm.equalsIgnoreCase("true");
         
-        ManipulationMetadata mm = new ManipulationMetadata(metadata);
+        PojoMetadata meta = getFactory().getPojoMetadata();
 
         Element[] hooksMetadata = metadata.getElements("callback");
-        for (int i = 0; i < hooksMetadata.length; i++) {
+        for (int i = 0; hooksMetadata != null && i < hooksMetadata.length; i++) {
             String method = hooksMetadata[i].getAttribute("method");
             if (method == null) {
                 throw new ConfigurationException("Lifecycle callback : A callback needs to contains a method attribute");
             }
             
-            MethodMetadata met = mm.getMethod(method, new String[0]);
+            MethodMetadata met = meta.getMethod(method, new String[0]);
             
             int transition = -1;
             String trans = hooksMetadata[i].getAttribute("transition");
-            if (trans != null) {
+            if (trans == null) {
+                throw new ConfigurationException("Lifecycle callback : the transition attribute is missing");
+            } else {
                 if (trans.equalsIgnoreCase("validate")) {
                     transition = LifecycleCallback.VALIDATE;
                 } else if (trans.equalsIgnoreCase("invalidate")) {
                     transition = LifecycleCallback.INVALIDATE; 
                 } else {
-                    throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + transition);
+                    throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + trans);
                 }
-            } else {
-                throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition");
             }
             
-            LifecycleCallback hk = null;
-            if (met != null) { 
-                hk = new LifecycleCallback(this, transition, met);
+            LifecycleCallback callback = null;
+            if (met == null) {
+                callback = new LifecycleCallback(this, transition, method);
             } else {
-                hk = new LifecycleCallback(this, transition, method);
+                callback = new LifecycleCallback(this, transition, met);
             }
-            addCallback(hk);
+            addCallback(callback);
         }
     }
 
@@ -127,7 +126,8 @@
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-    } // Do nothing during the start
+     // Do nothing during the start
+    } 
 
     /**
      * Stop the handler.
@@ -162,13 +162,13 @@
                 try {
                     m_callbacks[i].call();
                 } catch (NoSuchMethodException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found", e);
-                    getInstanceManager().stop();
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found");
+                    throw new IllegalStateException(e.getMessage());
                 } catch (IllegalAccessException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible", e);
-                    getInstanceManager().stop();
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible");
+                    throw new IllegalStateException(e.getMessage());
                 } catch (InvocationTargetException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : " + e.getTargetException().getMessage());
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());
                     getInstanceManager().setState(ComponentInstance.INVALID);
                 }
             }
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 41b7250..6d00b3b 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
@@ -24,11 +24,10 @@
 import org.apache.felix.ipojo.ConfigurationException;
 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.ComponentTypeDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.parser.PojoMetadata;
 
 /**
  * Lifecycle Controller handler.
@@ -51,9 +50,9 @@
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
     public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
-        Element[] lc = metadata.getElements("controller");
-        String field = lc[0].getAttribute("field");   
-        getInstanceManager().register(this, new FieldMetadata[] {new FieldMetadata(field, "boolean")}, null);
+        Element[] controller = metadata.getElements("controller");
+        String field = controller[0].getAttribute("field");   
+        getInstanceManager().register(new FieldMetadata(field, "boolean"), this);
     }
 
     /**
@@ -70,38 +69,42 @@
      * Nothing to do. 
      * @see org.apache.felix.ipojo.Handler#stop()
      */
-    public void stop() { }
+    public void stop() { 
+        // Nothing to do.
+    }
     
     /**
      * GetterCallback.
+     * @param pojo : the pojo object on which the field is accessed
      * Return the stored value.
      * @param field : field name.
-     * @param o : value given by the previous handler.
+     * @param value : value given by the previous handler.
      * @return : the handler state.
      */
-    public Object getterCallback(String field, Object o) {
+    public Object onGet(Object pojo, String field, Object value) {
         return new Boolean(m_state);
     }
     
     /**
      * SetterCallback.
+     * @param pojo : the pojo object on which the field is accessed
      * Store the new field value & invalidate / validate the handler is required.
      * @param field : field name.
-     * @param o : new value.
+     * @param value : new value.
      */
-    public void setterCallback(String field, Object o) {
-        if (o instanceof Boolean) {
-            boolean nv = ((Boolean) o).booleanValue();
-            if (nv != m_state) {
-                m_state = nv;
+    public void onSet(Object pojo, String field, Object value) {
+        if (value instanceof Boolean) {
+            boolean newValue = ((Boolean) value).booleanValue();
+            if (newValue != m_state) {
+                m_state = newValue;
                 if (m_state) {
-                    ((InstanceManager) getInstance()).setState(ComponentInstance.VALID);
+                    ((InstanceManager) getHandlerManager()).setState(ComponentInstance.VALID);
                 } else {
-                    ((InstanceManager) getInstance()).setState(ComponentInstance.INVALID);
+                    ((InstanceManager) getHandlerManager()).setState(ComponentInstance.INVALID);
                 }
             }
         } else {
-            log(Logger.ERROR, "Boolean expected for the lifecycle controller");
+            error("Boolean expected for the lifecycle controller");
             getInstanceManager().stop();
         }
     }
@@ -109,28 +112,28 @@
     /**
      * Initialize the component factory.
      * The controller field is checked to avoid configure check.
-     * @param cd : component description
+     * @param desc : component description
      * @param metadata : component type metadata
      * @throws ConfigurationException : occurs if the controller field is not in the POJO class or is not a boolean.
-     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
      */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
         String field = null;
-        Element[] lc = metadata.getElements("controller");
+        Element[] controller = metadata.getElements("controller");
         // Use only the first controller
-        field = lc[0].getAttribute("field");
+        field = controller[0].getAttribute("field");
         if (field == null) {
             throw new ConfigurationException("Lifecycle controller : the controller element needs to have a field attribute");
         }
         
-        ManipulationMetadata mm = new ManipulationMetadata(metadata);
-        FieldMetadata fm = mm.getField(field);
-        if (fm == null) {
+        PojoMetadata method = getFactory().getPojoMetadata();
+        FieldMetadata fieldMetadata = method.getField(field);
+        if (fieldMetadata == null) {
             throw new ConfigurationException("Lifecycle controller : The field " + field + " does not exist in the class");
         }
         
-        if (!fm.getFieldType().equalsIgnoreCase("boolean")) {
-            throw new ConfigurationException("Lifecycle controller : The field " + field + " must be a boolean (" + fm.getFieldType() + " found)");
+        if (!fieldMetadata.getFieldType().equalsIgnoreCase("boolean")) {
+            throw new ConfigurationException("Lifecycle controller : The field " + field + " must be a boolean (" + fieldMetadata.getFieldType() + " found)");
         }
     }
 
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
deleted file mode 100644
index f6b3b6f..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
+++ /dev/null
@@ -1,391 +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.handlers.providedservice;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.parser.ParseUtils;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * Represent a property i.e. a set : [name, type, value]. A property can be
- * attached to a field. The value of the property is thefield value. When the
- * value change, the published value change too.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class Property {
-
-    /**
-     * A property is link with a service. This field represent this provided
-     * service. m_providedService : ProvidedService
-     */
-    private ProvidedService m_providedService;
-
-    /**
-     * Value of the property (before we know the type).
-     */
-    private Object m_value;
-
-    /**
-     * Field of the property.
-     */
-    private String m_field;
-
-    /**
-     * Name of the property.
-     */
-    private String m_name;
-
-    /**
-     * Type of the property.
-     */
-    private String m_type;
-
-    /**
-     * String value of the property (initial value).
-     */
-    private String m_initialValue;
-
-    /**
-     * Property constructor.
-     * 
-     * @param ps : the provided service
-     * @param name : name of the property
-     * @param field : name of the field (if a field is attached to the property)
-     * @param type : type of the property
-     * @param value : initial value of the property
-     */
-    public Property(ProvidedService ps, String name, String field, String type, String value) {
-        m_providedService = ps;
-        m_name = name;
-        m_field = field;
-        m_type = type;
-        m_initialValue = value;
-
-        // Dynamic property case :
-        if (m_field != null && m_name == null) {
-            m_name = m_field;
-        }
-
-        if (m_initialValue != null) {
-            setValue(m_initialValue);
-        }
-    }
-
-    /**
-     * Property constructor. This constructor is used only for non-field
-     * property (property not attached to a field).
-     * 
-     * @param ps : the provided service
-     * @param name : the name of the property
-     * @param value : the value of the property
-     */
-    public Property(ProvidedService ps, String name, Object value) {
-        m_providedService = ps;
-        m_name = name;
-        m_type = value.getClass().getName();
-        m_value = value;
-    }
-
-    /**
-     * Get the property value.
-     * @return the Object value of the property
-     */
-    protected Object get() {
-        return m_value;
-    }
-
-    /**
-     * This method is automaticaly called when the value of the property is
-     * changed. Set the value of a property.
-     * 
-     * @param s : the new value of the property (in String)
-     */
-    protected void set(String s) {
-        setValue(s);
-    }
-
-    /**
-     * This method is called when the value of the property is changed. Set the
-     * value of a property.
-     * 
-     * @param o : the new value of the property (object)
-     */
-    protected void set(Object o) {
-        // Is the object is directly assignable to the property, affect it.
-        if (!(o instanceof String) || m_type.equals("java.lang.String")) {
-            m_value = o;
-        } else {
-            // If the object is a String, we must recreate the object from the String form
-            if (o instanceof String) {
-                setValue((String) o);
-            } else {
-                // Error, the given property cannot be injected.
-                throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type + " expected");
-            }
-        }
-    }
-
-    /**
-     * Set the provided service of this property.
-     * 
-     * @param ps : the provided service to attached.
-     */
-    void setProvidedService(ProvidedService ps) {
-        m_providedService = ps;
-    }
-
-    /**
-     * Set the value of the property.
-     * 
-     * @param value : value of the property (String)
-     */
-    private void setValue(String value) {
-
-        // Array :
-        if (m_type.endsWith("[]")) {
-            String internalType = m_type.substring(0, m_type.length() - 2);
-            setArrayValue(internalType, ParseUtils.parseArrays(value));
-            return;
-        }
-
-        // Simple :
-        if ("string".equals(m_type) || "String".equals(m_type)) {
-            m_value = new String(value);
-            return;
-        }
-        if ("boolean".equals(m_type)) {
-            m_value = new Boolean(value);
-            return;
-        }
-        if ("byte".equals(m_type)) {
-            m_value = new Byte(value);
-            return;
-        }
-        if ("short".equals(m_type)) {
-            m_value = new Short(value);
-            return;
-        }
-        if ("int".equals(m_type)) {
-            m_value = new Integer(value);
-            return;
-        }
-        if ("long".equals(m_type)) {
-            m_value = new Long(value);
-            return;
-        }
-        if ("float".equals(m_type)) {
-            m_value = new Float(value);
-            return;
-        }
-        if ("double".equals(m_type)) {
-            m_value = new Double(value);
-            return;
-        }
-
-        // Else it is a neither a primitive type neither a String -> create the
-        // object by calling a constructor with a string in argument.
-        try {
-            Class c = m_providedService.getInstanceManager().getContext().getBundle().loadClass(m_type);
-            // Class string =
-            // m_providedService.getComponentManager().getContext().getBundle().loadClass("java.lang.String");
-            Constructor cst = c.getConstructor(new Class[] { String.class });
-            m_value = cst.newInstance(new Object[] { value });
-        } catch (ClassNotFoundException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Class not found exception in setValue on " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (SecurityException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Security Exception in setValue on " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (NoSuchMethodException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Constructor not found exeption in setValue on " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (IllegalArgumentException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Argument problem to call the constructor of the type " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (InstantiationException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Instantiation problem  " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (IllegalAccessException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Illegal Access Exception in setValue on " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (InvocationTargetException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Invocation problem " + m_type + " : " + e.getTargetException().getMessage());
-            m_providedService.getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-
-    /**
-     * Set a array value to the current property.
-     * 
-     * @param internalType : internal array type
-     * @param values : the new value
-     */
-    private void setArrayValue(String internalType, String[] values) {
-        if ("string".equals(internalType) || "String".equals(internalType)) {
-            m_value = values;
-            return;
-        }
-        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();
-            }
-            m_value = bool;
-            return;
-        }
-        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();
-            }
-            m_value = byt;
-            return;
-        }
-        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();
-            }
-            m_value = shor;
-            return;
-        }
-        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();
-            }
-            m_value = in;
-            return;
-        }
-        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();
-            }
-            m_value = ll;
-            return;
-        }
-        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();
-            }
-            m_value = fl;
-            return;
-        }
-        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();
-            }
-            m_value = dl;
-            return;
-        }
-
-        // Else it is a neither a primitive type neither a String -> create the
-        // object by calling a constructor with a string in argument.
-        try {
-            Class c = m_providedService.getInstanceManager().getContext().getBundle().loadClass(internalType);
-            Constructor cst = c.getConstructor(new Class[] { String.class });
-            Object[] ob = (Object[]) Array.newInstance(c, values.length);
-            for (int i = 0; i < values.length; i++) {
-                ob[i] = cst.newInstance(new Object[] { values[i] });
-            }
-            m_value = ob;
-            return;
-        } catch (ClassNotFoundException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Class not found exception in setArrayValue on " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (SecurityException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Security Exception in setArrayValue on " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (NoSuchMethodException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Constructor not found exception in setArrayValue on " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (IllegalArgumentException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Argument problem to call the constructor of the type " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (InstantiationException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Instantiation problem  " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (IllegalAccessException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Illegal Access Exception in setArrayValue on " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (InvocationTargetException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Invocation problem " + internalType + " : " + e.getTargetException().getMessage());
-            m_providedService.getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-
-    /**
-     * Get the stored value.
-     * @return the value of the property.
-     */
-    public Object getValue() {
-        return m_value;
-    }
-
-    /**
-     * Get the property name.
-     * @return the name of the property
-     */
-    public String getName() {
-        return m_name;
-    }
-
-    /**
-     * Get the property field.
-     * @return the field name of the property (null if the property has no
-     * field).
-     */
-    protected String getField() {
-        return m_field;
-    }
-
-    /**
-     * Set the type of the property.
-     * 
-     * @param type : the type to attached to the property
-     */
-    public void setType(String type) {
-        m_type = type;
-    }
-
-    /**
-     * Get the property type.
-     * @return the type of the property.
-     */
-    public String getType() {
-        return m_type;
-    }
-
-    /**
-     * Get the property initial value.
-     * @return the initial value of the property.
-     */
-    public String getInitialValue() {
-        return m_initialValue;
-    }
-
-}
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 ee1248a..4f1d52c 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
@@ -22,8 +22,9 @@
 import java.util.Enumeration;
 import java.util.Properties;
 
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.InstanceManager;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Property;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceReference;
@@ -55,6 +56,11 @@
      * Factory policy : SERVICE_FACTORY.
      */
     public static final int SERVICE_FACTORY = 1;
+    
+    /**
+     * Factory policy : STATIC_FACTORY.
+     */
+    public static final int STATIC_FACTORY = 2;
 
     /**
      * At this time, it is only the java interface full name.
@@ -80,7 +86,7 @@
     /**
      * Properties Array.
      */
-    private Property[] m_properties = new Property[0];
+    private Property[] m_properties;
 
     /**
      * Construct a provided service object.
@@ -96,8 +102,12 @@
         m_factoryPolicy = factoryPolicy;
         
         // Add instance name & factory name
-        addProperty(new Property(this, "instance.name", handler.getInstanceManager().getInstanceName()));       
-        addProperty(new Property(this, "factory.name", handler.getInstanceManager().getFactory().getName()));
+        try {
+            addProperty(new Property("instance.name", null, null, handler.getInstanceManager().getInstanceName(), String.class.getName(), handler.getInstanceManager(), handler));       
+            addProperty(new Property("factory.name", null, null, handler.getInstanceManager().getFactory().getFactoryName(), String.class.getName(), handler.getInstanceManager(), handler));
+        } catch (ConfigurationException e) {
+            m_handler.error("An exception occurs when adding instance.name and factory.name property : " + e.getMessage());
+        }
     }
 
     /**
@@ -113,22 +123,22 @@
     /**
      * Add the given property to the property list.
      * 
-     * @param p : the element to add
+     * @param prop : the element to add
      */
-    private synchronized void addProperty(Property p) {
+    private synchronized void addProperty(Property prop) {
         for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
-            if (m_properties[i] == p) {
+            if (m_properties[i] == prop) {
                 return;
             }
         }
 
-        if (m_properties.length > 0) {
+        if (m_properties == null) {
+            m_properties = new Property[] { prop };
+        } else {
             Property[] newProp = new Property[m_properties.length + 1];
             System.arraycopy(m_properties, 0, newProp, 0, m_properties.length);
-            newProp[m_properties.length] = p;
+            newProp[m_properties.length] = prop;
             m_properties = newProp;
-        } else {
-            m_properties = new Property[] { p };
         }
     }
 
@@ -148,7 +158,7 @@
 
         if (idx >= 0) {
             if ((m_properties.length - 1) == 0) {
-                m_properties = new Property[0];
+                m_properties = null;
             } else {
                 Property[] newPropertiesList = new Property[m_properties.length - 1];
                 System.arraycopy(m_properties, 0, newPropertiesList, 0, idx);
@@ -166,10 +176,10 @@
      * service is not published).
      */
     public ServiceReference getServiceReference() {
-        if (m_serviceRegistration != null) {
-            return m_serviceRegistration.getReference();
-        } else {
+        if (m_serviceRegistration == null) {
             return null;
+        } else {
+            return m_serviceRegistration.getReference();
         }
     }
 
@@ -189,9 +199,14 @@
             case SERVICE_FACTORY:
                 svc = m_handler.getInstanceManager().createPojoObject();
                 break;
+            case STATIC_FACTORY:
+                // In this case, we need to try to create a new pojo object, the factory method will handle the creation.
+                svc = m_handler.getInstanceManager().createPojoObject();
+                break;
             default:
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Unknown factory policy for " + m_serviceSpecification + " : " + m_factoryPolicy);
+                m_handler.error("[" + m_handler.getInstanceManager().getClassName() + "] Unknown factory policy for " + m_serviceSpecification + " : " + m_factoryPolicy);
                 getInstanceManager().stop();
+                break;
         }
         return svc;
     }
@@ -258,8 +273,8 @@
         // Contruct the service properties list
         Properties serviceProperties = new Properties();
         for (int i = 0; i < m_properties.length; i++) {
-            if (m_properties[i].get() != null) {
-                serviceProperties.put(m_properties[i].getName(), m_properties[i].get());
+            if (m_properties[i].getValue() != null) {
+                serviceProperties.put(m_properties[i].getName(), m_properties[i].getValue());
             }
         }
         return serviceProperties;
@@ -278,18 +293,9 @@
      * the service registry.
      */
     public synchronized void update() {
-        // Contruct the service properties list
-        Properties serviceProperties = getServiceProperties();
-
-        if (serviceProperties == null) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Cannot get the properties of the provided service");
-            getInstanceManager().stop();
-            return;
-        }
-
         // Update the service registration
         if (m_serviceRegistration != null) {
-            m_serviceRegistration.setProperties(serviceProperties);
+            m_serviceRegistration.setProperties(getServiceProperties());
         }
     }
 
@@ -302,8 +308,13 @@
         while (keys.hasMoreElements()) {
             String key = (String) keys.nextElement();
             Object value = props.get(key);
-            Property prop = new Property(this, key, value);
-            addProperty(prop);
+            Property prop;
+            try {
+                prop = new Property(key, null, null, value.toString(), value.getClass().getName(), getInstanceManager(), m_handler);
+                addProperty(prop);
+            } catch (ConfigurationException e) {
+                m_handler.error("The propagated property " + key + " cannot be pcreated correctly : " + e.getMessage());
+            }
         }
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
index 59f2cda..d8fe68a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
@@ -69,13 +69,13 @@
      * 
      * @param serviceSpecification : the provided contract
      * @param state : state (UNREGITRED | REGISTRED)
-     * @param sr : Service Registration (to obtain the reference), or null if
+     * @param ref : Service Registration (to obtain the reference), or null if
      * state is UNREGISTRED
      */
-    public ProvidedServiceDescription(String[] serviceSpecification, int state, ServiceReference sr) {
+    public ProvidedServiceDescription(String[] serviceSpecification, int state, ServiceReference ref) {
         m_serviceSpecification = serviceSpecification;
         m_state = state;
-        m_serviceReference = sr;
+        m_serviceReference = ref;
         // m_parent = parent;
     }
 
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 a791797..1fc3e1d 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
@@ -19,7 +19,6 @@
 package org.apache.felix.ipojo.handlers.providedservice;
 
 import java.lang.reflect.Field;
-import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -28,10 +27,10 @@
 import java.util.Set;
 
 import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.IPojoConfiguration;
+import org.apache.felix.ipojo.HandlerFactory;
 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.ComponentTypeDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.handlers.dependency.Dependency;
@@ -40,9 +39,10 @@
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
 import org.apache.felix.ipojo.parser.ManifestMetadataParser;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.parser.ParseUtils;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Property;
 import org.osgi.framework.Bundle;
 
 /**
@@ -60,21 +60,21 @@
     /**
      * Add a provided service to the list .
      * 
-     * @param ps : the provided service to add
+     * @param svc : the provided service to add
      */
-    private void addProvidedService(ProvidedService ps) {
+    private void addProvidedService(ProvidedService svc) {
         // 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] == svc) { return; }
         }
 
         if (m_providedServices.length > 0) {
             ProvidedService[] newPS = new ProvidedService[m_providedServices.length + 1];
             System.arraycopy(m_providedServices, 0, newPS, 0, m_providedServices.length);
-            newPS[m_providedServices.length] = ps;
+            newPS[m_providedServices.length] = svc;
             m_providedServices = newPS;
         } else {
-            m_providedServices = new ProvidedService[] { ps };
+            m_providedServices = new ProvidedService[] { svc };
         }
     }
 
@@ -97,7 +97,6 @@
         m_providedServices = new ProvidedService[0];
         // Create the dependency according to the component metadata
         Element[] providedServices = componentMetadata.getElements("Provides");
-        List fields = new ArrayList();
         for (int i = 0; i < providedServices.length; i++) {
             String[] serviceSpecifications = ParseUtils.parseArrays(providedServices[i].getAttribute("interface")); // Set by the initialize component factory.
             
@@ -107,62 +106,54 @@
             if (fact != null && "service".equalsIgnoreCase(fact)) {
                 factory = ProvidedService.SERVICE_FACTORY;
             }
-
-            // Then create the provided service
-            ProvidedService ps = new ProvidedService(this, serviceSpecifications, factory);
-
-            Element[] props = providedServices[i].getElements("Property");
-            Property[] properties = new Property[props.length];
-            for (int j = 0; j < props.length; j++) {
-                String name = props[j].getAttribute("name");
-                String value = props[j].getAttribute("value");
-                String type = props[j].getAttribute("type");
-                String field = props[j].getAttribute("field");
-
-                if (name != null && configuration.get(name) != null && configuration.get(name) instanceof String) {
-                    value = (String) configuration.get(name);
-                } else {
-                    if (field != null && configuration.get(field) != null && configuration.get(field) instanceof String) {
-                        value = (String) configuration.get(field);
-                    }
-                }
-
-                Property prop = new Property(ps, name, field, type, value);
-                properties[j] = prop;
-                
-                // Check if the instance configuration has a value for this property
-                Object o = configuration.get(prop.getName()); 
-                if (o != null && ! (o instanceof String)) {
-                    prop.set(o);
-                } else {
-                    if (field != null) {
-                        o = configuration.get(field);
-                        if (o != null && !(o instanceof String)) {
-                            prop.set(configuration.get(field));
-                        }
-                    }
-                }
-                
-                if (field != null) {
-                    fields.add(new FieldMetadata(field, type));
-                }
+            if (fact != null && "method".equalsIgnoreCase(fact)) {
+                factory = ProvidedService.STATIC_FACTORY;
             }
 
-            // Attached to properties to the provided service
-            ps.setProperties(properties);
+            // Then create the provided service
+            ProvidedService svc = new ProvidedService(this, serviceSpecifications, factory);
 
-            if (checkProvidedService(ps)) {
-                addProvidedService(ps);
+            Element[] props = providedServices[i].getElements("Property");
+            if (props != null) {
+                //Property[] properties = new Property[props.length];
+                Property[] properties = new Property[props.length];
+                for (int j = 0; j < props.length; j++) {
+                    String name = props[j].getAttribute("name");
+                    String value = props[j].getAttribute("value");
+                    String type = props[j].getAttribute("type");
+                    String field = props[j].getAttribute("field");
+
+                    Property prop = new Property(name, field, null, value, type, getInstanceManager(), this);
+                    properties[j] = prop;
+
+                    // Check if the instance configuration has a value for this property                    
+                    Object object = configuration.get(prop.getName());
+                    if (object != null) {
+                        prop.setValue(object);
+                    }
+                    
+                    if (field != null) {
+                        getInstanceManager().register(new FieldMetadata(field, type), this);
+                        // Cannot register the property as the interception is necessary to deal with registration update.
+                    }
+                }
+
+                // Attach to properties to the provided service
+                svc.setProperties(properties);
+            }
+
+            if (checkProvidedService(svc)) {
+                addProvidedService(svc);
             } else {
-                String itfs = "";
+                StringBuffer itfs = new StringBuffer();
                 for (int j = 0; j < serviceSpecifications.length; j++) {
-                    itfs = itfs + " " + serviceSpecifications[j];
+                    itfs.append(' ');
+                    itfs.append(serviceSpecifications[j]);
                 }
                 throw new ConfigurationException("[" + getInstanceManager().getInstanceName() + "] The provided service" + itfs + " is not valid");                
             }
 
         }
-        getInstanceManager().register(this, (FieldMetadata[]) fields.toArray(new FieldMetadata[fields.size()]), null);
     }
     
     /**
@@ -185,8 +176,8 @@
 
         // Look for parent class.
         if (parent != null) {
-            Class cl = bundle.loadClass(parent);
-            collectInterfacesFromClass(cl, result, bundle);
+            Class clazz = bundle.loadClass(parent);
+            collectInterfacesFromClass(clazz, result, bundle);
         }
 
         return result;
@@ -195,78 +186,78 @@
     /**
      * Look for inherited interfaces.
      * @param clazz : interface name to explore (class object)
-     * @param l : set (accumulator)
-     * @param b : bundle
+     * @param acc : set (accumulator)
+     * @param bundle : bundle
      * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
      */
-    private void collectInterfaces(Class clazz, Set l, Bundle b) throws ClassNotFoundException {
+    private void collectInterfaces(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
         Class[] clazzes = clazz.getInterfaces();
         for (int i = 0; i < clazzes.length; i++) {
-            l.add(clazzes[i].getName());
-            collectInterfaces(clazzes[i], l, b);
+            acc.add(clazzes[i].getName());
+            collectInterfaces(clazzes[i], acc, bundle);
         }
     }
     
     /**
      * Collect interfaces for the given class.
      * This method explores super class to.
-     * @param cl : class object.
-     * @param l : set of implemented interface (accumulator)
-     * @param b : bundle.
+     * @param clazz : class object.
+     * @param acc : set of implemented interface (accumulator)
+     * @param bundle : bundle.
      * @throws ClassNotFoundException : occurs if an interface cannot be load.
      */
-    private void collectInterfacesFromClass(Class cl, Set l, Bundle b) throws ClassNotFoundException {
-        Class[] clazzes = cl.getInterfaces();
+    private void collectInterfacesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+        Class[] clazzes = clazz.getInterfaces();
         for (int i = 0; i < clazzes.length; i++) {
-            l.add(clazzes[i].getName());
-            collectInterfaces(clazzes[i], l, b);
+            acc.add(clazzes[i].getName());
+            collectInterfaces(clazzes[i], acc, bundle);
         }
         // Iterate on parent classes
-        Class sup = cl.getSuperclass();
+        Class sup = clazz.getSuperclass();
         if (sup != null) {
-            collectInterfacesFromClass(sup, l, b);
+            collectInterfacesFromClass(sup, acc, bundle);
         }
     }
 
     /**
      * Check the provided service given in argument in the sense that the metadata are consistent.
-     * @param ps : the provided service to check.
+     * @param svc : the provided service to check.
      * @return true if the provided service is correct
      * @throws ConfigurationException : the checked provided service is not correct.
      */
-    private boolean checkProvidedService(ProvidedService ps) throws ConfigurationException {        
-        for (int i = 0; i < ps.getServiceSpecification().length; i++) {
-            String specName = ps.getServiceSpecification()[i];
+    private boolean checkProvidedService(ProvidedService svc) throws ConfigurationException {        
+        for (int i = 0; i < svc.getServiceSpecification().length; i++) {
+            String specName = svc.getServiceSpecification()[i];
             
             // Check service level dependencies
             try {
                 Class spec = getInstanceManager().getFactory().loadClass(specName);
                 Field specField = spec.getField("specification");
-                Object o = specField.get(null);
-                if (o instanceof String) {
-                    Element specification = ManifestMetadataParser.parse((String) o);
+                Object specif = specField.get(null);
+                if (specif instanceof String) {
+                    Element specification = ManifestMetadataParser.parse((String) specif);
                     Element[] deps = specification.getElements("requires");
-                    for (int j = 0; j < deps.length; j++) {
-                        Dependency d = getAttachedDependency(deps[j]);
-                        if (d != null) {
+                    for (int j = 0; deps != null && j < deps.length; j++) {
+                        Dependency dep = getAttachedDependency(deps[j]);
+                        if (dep != null) {
                             // Fix service-level dependency flag
-                            d.setServiceLevelDependency();
+                            dep.setServiceLevelDependency();
                         }
-                        isDependencyCorrect(d, deps[j]);
+                        isDependencyCorrect(dep, deps[j]);
                     }
                 } else {
-                    throw new ConfigurationException("Provides  : 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 " + svc.getServiceSpecification()[i] + " need to be a String");
                 }
             } catch (NoSuchFieldException e) {
                 return true; // No specification field
             } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Provides  : The service specification " + ps.getServiceSpecification()[i] + " cannot be load");
+                throw new ConfigurationException("Provides  : The service specification " + svc.getServiceSpecification()[i] + " cannot be load");
             } catch (IllegalArgumentException e) {
-                throw new ConfigurationException("Provides  : 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 " + svc.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
             } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Provides  : 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 " + svc.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
             } catch (ParseException e) {
-                throw new ConfigurationException("Provides  :  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 " + svc.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage());
             }
         }
 
@@ -279,20 +270,20 @@
      * @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) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
-        if (dh == null) { return null; }
+        DependencyHandler handler = (DependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":requires");
+        if (handler == null) { return null; }
 
-        String id = element.getAttribute("id");
-        if (id != null) {
+        String identity = element.getAttribute("id");
+        if (identity != null) {
             // Look for dependency Id
-            for (int i = 0; i < dh.getDependencies().length; i++) {
-                if (dh.getDependencies()[i].getId().equals(id)) { return dh.getDependencies()[i]; }
+            for (int i = 0; i < handler.getDependencies().length; i++) {
+                if (handler.getDependencies()[i].getId().equals(identity)) { return handler.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]; }
+        for (int i = 0; i < handler.getDependencies().length; i++) {
+            if (handler.getDependencies()[i].getSpecification().equals(requirement)) { return handler.getDependencies()[i]; }
         }
 
         return null;
@@ -334,6 +325,7 @@
      * @see org.apache.felix.ipojo.Handler#stop()
      */
     public void stop() {
+        //Nothing to do.
     }
 
     /**
@@ -341,31 +333,34 @@
      * 
      * @see org.apache.felix.ipojo.Handler#start()
      */
-    public void start() { }
+    public void start() {
+        // Nothing to do.
+    }
 
     /**
      * Setter Callback Method.
      * Check if the modified field is a property to update the value.
+     * @param pojo : the pojo object on which the field is accessed
      * @param fieldName : field name
      * @param value : new value
-     * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String,
-     * java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onSet(Object,
+     * java.lang.String, java.lang.Object)
      */
-    public void setterCallback(String fieldName, Object value) {
+    public void onSet(Object pojo, String fieldName, Object value) {
         // Verify that the field name correspond to a dependency
         for (int i = 0; i < m_providedServices.length; i++) {
-            ProvidedService ps = m_providedServices[i];
+            ProvidedService svc = m_providedServices[i];
             boolean update = false;
-            for (int j = 0; j < ps.getProperties().length; j++) {
-                Property prop = ps.getProperties()[j];
-                if (fieldName.equals(prop.getField())) {
+            for (int j = 0; j < svc.getProperties().length; j++) {
+                Property prop = svc.getProperties()[j];
+                if (fieldName.equals(prop.getField()) && ! prop.getValue().equals(value)) {
                     // it is the associated property
-                    prop.set(value);
+                    prop.setValue(value);
                     update = true;
                 }
             }
             if (update) {
-                ps.update();
+                svc.update();
             }
         }
         // Else do nothing
@@ -374,20 +369,21 @@
     /**
      * Getter Callback Method.
      * Check if the field is a property to push the stored value.
+     * @param pojo : the pojo object on which the field is accessed
      * @param fieldName : field name
      * @param value : value pushed by the previous handler
      * @return the stored value or the previous value.
-     * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String,
-     * java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onGet(Object,
+     * java.lang.String, java.lang.Object)
      */
-    public Object getterCallback(String fieldName, Object value) {
+    public Object onGet(Object pojo, String fieldName, Object value) {
         for (int i = 0; i < m_providedServices.length; i++) {
-            ProvidedService ps = m_providedServices[i];
-            for (int j = 0; j < ps.getProperties().length; j++) {
-                Property prop = ps.getProperties()[j];
+            ProvidedService svc = m_providedServices[i];
+            for (int j = 0; j < svc.getProperties().length; j++) {
+                Property prop = svc.getProperties()[j];
                 if (fieldName.equals(prop.getField())) {
                     // it is the associated property
-                    return prop.get();
+                    return prop.getValue();
                 }
             }
         }
@@ -452,12 +448,12 @@
         ProvidedServiceHandlerDescription pshd = new ProvidedServiceHandlerDescription(this);
 
         for (int j = 0; j < getProvidedService().length; j++) {
-            ProvidedService ps = getProvidedService()[j];
-            ProvidedServiceDescription psd = new ProvidedServiceDescription(ps.getServiceSpecification(), ps.getState(), ps.getServiceReference());
+            ProvidedService svc = getProvidedService()[j];
+            ProvidedServiceDescription psd = new ProvidedServiceDescription(svc.getServiceSpecification(), svc.getState(), svc.getServiceReference());
 
             Properties props = new Properties();
-            for (int k = 0; k < ps.getProperties().length; k++) {
-                Property prop = ps.getProperties()[k];
+            for (int k = 0; k < svc.getProperties().length; k++) {
+                Property prop = svc.getProperties()[k];
                 if (prop.getValue() != null) {
                     props.put(prop.getName(), prop.getValue().toString());
                 }
@@ -475,36 +471,32 @@
      */
     public void reconfigure(Dictionary dict) {
         for (int j = 0; j < getProvidedService().length; j++) {
-            ProvidedService ps = getProvidedService()[j];
-            Property[] props = ps.getProperties();
+            ProvidedService svc = getProvidedService()[j];
+            Property[] props = svc.getProperties();
             boolean update = false;
             for (int k = 0; k < props.length; k++) {
                 if (dict.get(props[k].getName()) != null) {
                     update = true;
-                    if (dict.get(props[k].getName()) instanceof String) {
-                        props[k].set((String) dict.get(props[k].getName()));
-                    } else {
-                        props[k].set(dict.get(props[k].getName()));
-                    }
+                    props[k].setValue(dict.get(props[k].getName()));
                 }
             }
             if (update) {
-                ps.update();
+                svc.update();
             }
         }
     }
 
     /**
      * Initialize the component type.
-     * @param cd : component type description to populate.
+     * @param desc : component type description to populate.
      * @param metadata : component type metadata.
      * @throws ConfigurationException : occurs when the POJO does not implement any interfaces.
-     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
      */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
         // Change ComponentInfo
         Element[] provides = metadata.getElements("provides");
-        ManipulationMetadata manipulation = new ManipulationMetadata(metadata);
+        PojoMetadata manipulation = getFactory().getPojoMetadata();
 
         for (int i = 0; i < provides.length; i++) {
          // First : create the serviceSpecification list
@@ -512,7 +504,7 @@
             String parent = manipulation.getSuperClass();
             Set all = null;
             try {
-                all = computeInterfaces(serviceSpecification, parent, cd.getBundleContext().getBundle());
+                all = computeInterfaces(serviceSpecification, parent, desc.getBundleContext().getBundle());
             } catch (ClassNotFoundException e) {
                 throw new ConfigurationException("A interface cannot be loaded : " + e.getMessage());
             }
@@ -522,35 +514,37 @@
                 List itfs = ParseUtils.parseArraysAsList(serviceSpecificationStr);
                 for (int j = 0; j < itfs.size(); j++) {
                     if (! all.contains(itfs.get(j))) {
-                        throw new ConfigurationException("The specification " + itfs.get(j) + " is not implemented by " + cd.getClassName());
+                        throw new ConfigurationException("The specification " + itfs.get(j) + " is not implemented by " + desc.getClassName());
                     }
                 }
                 all = new HashSet(itfs);
             }
             
-            if (all.size() == 0) {
+            if (all.isEmpty()) {
                 throw new ConfigurationException("Provides  : Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)");
             }
 
-            String specs = null;
+            StringBuffer specs = null;
             Set set = new HashSet(all);
-            Iterator it = set.iterator(); 
-            while (it.hasNext()) {
-                String sp = (String) it.next();
-                cd.addProvidedServiceSpecification(sp);
+            Iterator iterator = set.iterator(); 
+            while (iterator.hasNext()) {
+                String spec = (String) iterator.next();
+                desc.addProvidedServiceSpecification(spec);
                 if (specs == null) {
-                    specs = "{" + sp;
+                    specs = new StringBuffer("{");
+                    specs.append(spec);
                 } else {
-                    specs += "," + sp;
+                    specs.append(',');
+                    specs.append(spec);
                 }
             }
             
-            specs += "}";
+            specs.append('}');
             
-            provides[i].addAttribute(new Attribute("interface", specs)); // Add interface attribute to avoid checking in the configure method
+            provides[i].addAttribute(new Attribute("interface", specs.toString())); // Add interface attribute to avoid checking in the configure method
 
             Element[] props = provides[i].getElements("property");
-            for (int j = 0; j < props.length; j++) {
+            for (int j = 0; props != null && j < props.length; j++) {
                 String name = props[j].getAttribute("name");
                 String value = props[j].getAttribute("value");
                 String type = props[j].getAttribute("type");
@@ -566,15 +560,22 @@
                     if (field == null) {
                         throw new ConfigurationException("The property " + name + " has neither type neither field.");
                     }
-                    FieldMetadata fm = manipulation.getField(field);
-                    if (fm == null) {
+                    FieldMetadata fieldMeta = manipulation.getField(field);
+                    if (fieldMeta == null) {
                         throw new ConfigurationException("A declared property was not found in the class : " + field);
                     }
-                    type = fm.getFieldType();
+                    type = fieldMeta.getFieldType();
                     props[j].addAttribute(new Attribute("type", type));
                 }
+                
+                // Is the property set to immutable
+                boolean immutable = false;
+                String imm = props[j].getAttribute("immutable");
+                if (imm != null && imm.equalsIgnoreCase("true")) {
+                    immutable = true;
+                }
 
-                cd.addProperty(new PropertyDescription(name, type, value));
+                desc.addProperty(new PropertyDescription(name, type, value, immutable));
             }
         }
     }
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 d2bb779..59601f9 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
@@ -40,10 +40,10 @@
 
     /**
      * Constructor.
-     * @param h : handler.
+     * @param handler : handler.
      */
-    public ProvidedServiceHandlerDescription(Handler h) {
-        super(h);
+    public ProvidedServiceHandlerDescription(Handler handler) {
+        super(handler);
     }
 
     /**
@@ -83,17 +83,18 @@
     public Element getHandlerInfo() {
         Element services = super.getHandlerInfo();
         for (int i = 0; i < m_providedServices.length; i++) {
-            Element service = new Element("provides", "");
-            String spec = "[";
+            Element service = new Element("provides", null);
+            StringBuffer spec = new StringBuffer("[");
             for (int j = 0; j < m_providedServices[i].getServiceSpecification().length; j++) {
                 if (j == 0) {
-                    spec += m_providedServices[i].getServiceSpecification()[j];
+                    spec.append(m_providedServices[i].getServiceSpecification()[j]);
                 } else {
-                    spec += ", " + m_providedServices[i].getServiceSpecification()[j];
+                    spec.append(',');
+                    spec.append(m_providedServices[i].getServiceSpecification()[j]);
                 }
             }
-            spec += "]";
-            service.addAttribute(new Attribute("specifications", spec));
+            spec.append(']');
+            service.addAttribute(new Attribute("specifications", spec.toString()));
 
             if (m_providedServices[i].getState() == ProvidedService.REGISTERED) {
                 service.addAttribute(new Attribute("state", "registered"));
@@ -102,12 +103,12 @@
                 service.addAttribute(new Attribute("state", "unregistered"));
             }
             
-            Iterator it = m_providedServices[i].getProperties().keySet().iterator();
-            while (it.hasNext()) {
-                Element prop = new Element("property", "");
-                String k = (String) it.next();
-                prop.addAttribute(new Attribute("name", k));
-                prop.addAttribute(new Attribute("value", m_providedServices[i].getProperties().getProperty(k).toString()));
+            Iterator iterator = m_providedServices[i].getProperties().keySet().iterator();
+            while (iterator.hasNext()) {
+                Element prop = new Element("property", null);
+                String name = (String) iterator.next();
+                prop.addAttribute(new Attribute("name", name));
+                prop.addAttribute(new Attribute("value", m_providedServices[i].getProperties().getProperty(name).toString()));
                 service.addElement(prop);
             }
             services.addElement(service);
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java
index 9c6ea8d..bc272d0 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java
@@ -62,45 +62,32 @@
     public String getFieldType() { return m_type; }
     
     /**
-     * Get the 'reflective' type of the field.
+     * Get the 'reflective' type of the given type.
      * The reflective type is the type used by the Java Reflection API.
+     * @param type : the type to analyze to find the Java reflective type.
      * @return : the reflective type corresponding to this field.
      */
-    public String getReflectionType() {
+    public static String getReflectionType(String type) {
         // Primitive Array 
-        if (m_type.endsWith("[]") && m_type.indexOf(".") == -1) {
-            String arr = "";
-            for (int i = 0; i < m_type.length(); i++) {
-                if (m_type.charAt(i) == '[') { arr += '['; }
-            }
-            int index = m_type.indexOf('[');
-            String t = m_type.substring(0, index);
-            return arr + getInternalPrimitiveType(t);
+        if (type.endsWith("[]") && type.indexOf('.') == -1) {
+            int index = type.indexOf('[');
+            return '[' + getInternalPrimitiveType(type.substring(0, index));
         }
         // Non-Primitive Array 
-        if (m_type.endsWith("[]") && m_type.indexOf(".") != -1) {
-            String arr = "";
-            for (int i = 0; i < m_type.length(); i++) {
-                if (m_type.charAt(i) == '[') { arr += '['; }
-            }
-            int index = m_type.indexOf('[');
-            String t = m_type.substring(0, index);
-            return arr + "L" + t + ";";
+        if (type.endsWith("[]") && type.indexOf('.') != -1) {
+            int index = type.indexOf('[');
+            return "[L" + type.substring(0, index) + ";";
         }
-        // Simple type 
-        if (!m_type.endsWith("[]")) {
-            return m_type;
-        }
-        
-        return null;
+        // The type is not an array.
+        return type;
     }
     
     /**
      * Get the internal notation for primitive type.
-     * @param string : Stringform of the type
+     * @param string : String form of the type
      * @return the internal notation or null if not found
      */
-    private String getInternalPrimitiveType(String string) {
+    public static String getInternalPrimitiveType(String string) {
         if (string.equalsIgnoreCase("boolean")) {
             return "Z";
         }
@@ -125,7 +112,39 @@
         if (string.equalsIgnoreCase("double")) {
             return "D";
         }
-        System.err.println("No primitive type found for " + m_type);
+        return null;
+    }
+    
+    /**
+     * Get the iPOJO primitive type from the given primitive class.
+     * @param clazz : a primitive class
+     * @return the primitive type.
+     */
+    public static String getPrimitiveTypeByClass(Class clazz) {
+        if (clazz.equals(Boolean.TYPE)) {
+            return "boolean";
+        }
+        if (clazz.equals(Character.TYPE)) {
+            return "char";
+        }
+        if (clazz.equals(Byte.TYPE)) {
+            return "byte";
+        }
+        if (clazz.equals(Short.TYPE)) {
+            return "short";
+        }
+        if (clazz.equals(Integer.TYPE)) {
+            return "int";
+        }
+        if (clazz.equals(Float.TYPE)) {
+            return "float";
+        }
+        if (clazz.equals(Long.TYPE)) {
+            return "long";
+        }
+        if (clazz.equals(Double.TYPE)) {
+            return "double";
+        }
         return null;
     }
 
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 172338a..ea0709e 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
@@ -18,7 +18,9 @@
  */
 package org.apache.felix.ipojo.parser;
 
+import java.util.ArrayList;
 import java.util.Dictionary;
+import java.util.List;
 import java.util.Properties;
 
 import org.apache.felix.ipojo.metadata.Attribute;
@@ -32,11 +34,6 @@
 public class ManifestMetadataParser {
 
     /**
-     * Manifest Headers.
-     */
-    private Dictionary m_headers;
-
-    /**
      * Element list.
      */
     private Element[] m_elements = new Element[0];
@@ -47,24 +44,14 @@
      * @throws ParseException when a parsing error occurs
      */
     public Element[] getComponentsMetadata() throws ParseException {
-        Element[] components = m_elements[0].getElements("Component");
-        Element[] composites = m_elements[0].getElements("Composite");
-        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];
-            l++;
+        Element[] elems = m_elements[0].getElements();
+        List list = new ArrayList();
+        for (int i = 0; i < elems.length; i++) {
+            if (!"instance".equals(elems[i].getName())) {
+                list.add(elems[i]);
+            }
         }
-        for (int i = 0; i < composites.length; i++) {
-            all[l] = composites[i];
-            l++;
-        }
-        for (int i = 0; i < handlers.length; i++) {
-            all[l] = handlers[i];
-            l++;
-        }
-        return all;
+        return (Element[]) list.toArray(new Element[list.size()]);
     }
 
     /**
@@ -73,7 +60,10 @@
      * @throws ParseException : if the metadata cannot be parsed successfully
      */
     public Dictionary[] getInstances() throws ParseException {
-        Element[] configs = m_elements[0].getElements("Instance");
+        Element[] configs = m_elements[0].getElements("instance");
+        if (configs == null) {
+            return null;
+        }
         Dictionary[] dicts = new Dictionary[configs.length];
         for (int i = 0; i < configs.length; i++) {
             dicts[i] = parseInstance(configs[i]);
@@ -95,17 +85,18 @@
         if (name != null) {
             dict.put("name", instance.getAttribute("name"));
         }
-        
+
         if (comp == null) {
             throw new ParseException("An instance does not have the 'component' attribute");
         }
-        
-        dict.put("component", comp);
 
-        for (int i = 0; i < instance.getElements("property").length; i++) {
-            parseProperty(instance.getElements("property")[i], dict);
+        dict.put("component", comp);
+        Element[] props = instance.getElements("property");
+
+        for (int i = 0; props != null && i < props.length; i++) {
+            parseProperty(props[i], dict);
         }
-        
+
         return dict;
     }
 
@@ -122,10 +113,8 @@
         if (name == null) {
             throw new ParseException("A property does not have the 'name' attribute");
         }
-        // Final case : the property element has a 'value' attribute
-        if (value != null) {
-            dict.put(prop.getAttribute("name"), prop.getAttribute("value"));
-        } else {
+        //case : the property element has a 'value' attribute
+        if (value == null) {
             // Recursive case
             // Check if there is 'property' element
             Element[] subProps = prop.getElements("property");
@@ -137,6 +126,8 @@
                 parseProperty(subProps[i], dict2);
                 dict.put(name, dict2);
             }
+        } else {
+            dict.put(prop.getAttribute("name"), prop.getAttribute("value"));
         }
     }
 
@@ -146,13 +137,13 @@
      * @param elem : the element to add
      */
     private void addElement(Element elem) {
-        if (m_elements != null) {
+        if (m_elements == null) {
+            m_elements = new Element[] { elem };
+        } else {
             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;
-        } else {
-            m_elements = new Element[] { elem };
         }
     }
 
@@ -180,19 +171,18 @@
     }
 
     /**
-     * Parse the given dictionnary and create the instance managers.
+     * Parse the given dictionary and create the instance managers.
      * 
      * @param dict : the given headers of the manifest file
      * @throws ParseException : if any error occurs
      */
     public void parse(Dictionary dict) throws ParseException {
-        m_headers = dict;
-        String componentClassesStr = (String) m_headers.get("iPOJO-Components");
+        String componentClassesStr = (String) dict.get("iPOJO-Components");
         // Add the ipojo element inside the element list
         addElement(new Element("iPOJO", ""));
         parseElements(componentClassesStr.trim());
     }
-    
+
     /**
      * Parse the given header and create the instance managers.
      * 
@@ -222,57 +212,61 @@
     }
 
     /**
-     * Paser the given string.
+     * Parse the given string.
      * 
-     * @param s : the string to parse
+     * @param elems : the string to parse
      */
-    private void parseElements(String s) {
-        char[] string = s.toCharArray();
+    private void parseElements(String elems) {
+        char[] string = elems.toCharArray();
 
         for (int i = 0; i < string.length; i++) {
-            char c = string[i];
+            char current = string[i];
 
-            switch (c) {
+            switch (current) { //NOPMD
                 // Beginning of an attribute.
                 case '$':
-                    String attName = "";
-                    String attValue = "";
-                    String attNs = "";
+                    StringBuffer attName = new StringBuffer();
+                    StringBuffer attValue = new StringBuffer();
+                    StringBuffer attNs = null;
                     i++;
-                    c = string[i];
-                    while (c != '=') {
-                        if (c == ':') {
+                    current = string[i]; // Increment and get the new current char.
+                    while (current != '=') {
+                        if (current == ':') {
                             attNs = attName;
-                            attName = "";
+                            attName = new StringBuffer();
                         } else {
-                            attName = attName + c;
+                            attName.append(current);
                         }
-                        i = i + 1;
-                        c = string[i];
-                    }
-                    i++; // skip =
-                    i++; // skip "
-                    c = string[i];
-                    while (c != '"') {
-                        attValue = attValue + c;
                         i++;
-                        c = string[i];
+                        current = string[i];
+                    }
+                    i = i + 2; // skip ="
+                    current = string[i];
+                    while (current != '"') {
+                        attValue.append(current);
+                        i++;
+                        current = string[i]; // Increment and get the new current char.
                     }
                     i++; // skip "
-                    c = string[i];
+                    current = string[i];
 
-                    Attribute att = new Attribute(attName, attNs, attValue);
+                    Attribute att = null;
+                    if (attNs == null) {
+                        att = new Attribute(attName.toString(), attValue.toString());
+                    } else {
+                        att = new Attribute(attName.toString(), attNs.toString(), attValue.toString());
+                    }
                     m_elements[m_elements.length - 1].addAttribute(att);
                     break;
 
                 // End of an element
                 case '}':
                     Element lastElement = removeLastElement();
-                    if (m_elements.length != 0) {
+                    if (m_elements.length == 0) {
+                        addElement(lastElement);
+                    } else {
                         Element newQueue = m_elements[m_elements.length - 1];
                         newQueue.addElement(lastElement);
-                    } else {
-                        addElement(lastElement);
                     }
                     break;
 
@@ -282,19 +276,19 @@
 
                 // Default case
                 default:
-                    String name = "";
-                    String ns = "";
-                    c = string[i];
-                    while (c != ' ') {
-                        if (c == ':') {
-                            ns = name;
-                            name = "";
+                    StringBuffer name = new StringBuffer();
+                    StringBuffer namespace = null;
+                    current = string[i];
+                    while (current != ' ') {
+                        if (current == ':') {
+                            namespace = name;
+                            name = new StringBuffer();
                             i++;
-                            c = string[i];
+                            current = string[i];
                         } else {
-                            name = name + c;
+                            name.append(current);
                             i++;
-                            c = string[i];
+                            current = string[i]; // Increment and get the new current char.
                         }
                     }
                     // Skip spaces
@@ -302,8 +296,15 @@
                         i = i + 1;
                     }
                     i = i + 1; // skip {
-                    Element elem = new Element(name, ns);
+                    
+                    Element elem = null;
+                    if (namespace == null) {
+                        elem = new Element(name.toString(), null);
+                    } else {
+                        elem = new Element(name.toString(), namespace.toString());
+                    }
                     addElement(elem);
+                    
                     break;
             }
         }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
index 1a8b482..302c2d4 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.ipojo.parser;
 
+import java.lang.reflect.Method;
+
 import org.apache.felix.ipojo.metadata.Element;
 
 /**
@@ -27,22 +29,22 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class MethodMetadata {
-    
+
     /**
      * Name of the method.
      */
     private String m_name;
-    
+
     /**
      * Argument type array. 
      */
     private String[] m_arguments = new String[0];
-    
+
     /**
      * Returned type. 
      */
     private String m_return = "void";
-    
+
     /**
      * Constructor.
      * @param metadata : method manipulation element.
@@ -50,37 +52,77 @@
     MethodMetadata(Element metadata) {
         m_name = metadata.getAttribute("name");
         String arg = metadata.getAttribute("arguments");
-        String rt = metadata.getAttribute("return");
+        String result = metadata.getAttribute("return");
         if (arg != null) {
             m_arguments = ParseUtils.parseArrays(arg);
         }
-        if (rt != null) {
-            m_return = rt;
+        if (result != null) {
+            m_return = result;
         }
     }
-    
-    public String getMethodName() { return m_name; }
-    
-    public String[] getMethodArguments() { return m_arguments; }
-    
-    public String getMethodReturn() { return m_return; }
-    
+
+    public String getMethodName() {
+        return m_name;
+    }
+
+    public String[] getMethodArguments() {
+        return m_arguments;
+    }
+
+    public String getMethodReturn() {
+        return m_return;
+    }
+
     /**
      * Get the method unique identifier. For internal usage only.
      * @return the method identifier.
      */
     public String getMethodIdentifier() {
-        String id = m_name;
+        StringBuffer identifier = new StringBuffer(m_name);
         for (int i = 0; i < m_arguments.length; i++) {
-            String cn = m_arguments[i];
-            if (cn.endsWith("[]")) {
-                cn = cn.replace('[', '$');
-                cn = cn.substring(0, cn.length() - 1);
+            String arg = m_arguments[i];
+            identifier.append('$');
+            if (arg.endsWith("[]")) {
+                arg = arg.substring(0, arg.length() - 2);
+                identifier.append(arg.replace('.', '_'));
+                identifier.append("__"); // Replace [] by __
+            } else {
+                identifier.append(arg.replace('.', '_'));
             }
-            cn = cn.replace('.', '_');
-            id += cn;
         }
-        return id;
+        return identifier.toString();
+    }
+
+    /**
+     * Compute the method id for the given method. 
+     * @param method : Method object.
+     * @return the method id.
+     */
+    public static String computeMethodId(Method method) {
+        StringBuffer identifier = new StringBuffer(method.getName());
+        Class[] args = method.getParameterTypes();
+        for (int i = 0; i < args.length; i++) {
+            identifier.append('$'); // Argument separator.
+            if (args[i].isArray()) {
+                if (args[i].getComponentType().isPrimitive()) {
+                    // Primitive array
+                    identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType()));
+                } else {
+                    // Object array
+                    identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_'
+                }
+                identifier.append("__"); // Add __ (array)
+            } else {
+                if (args[i].isPrimitive()) {
+                    // Primitive type
+                    identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i]));
+                } else {
+                    // Object type
+                    identifier.append(args[i].getName().replace('.', '_')); // Replace '.' by '_'
+                }
+            }
+        }
+        return identifier.toString();
     }
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
index 08ceccb..e1597a3 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
@@ -18,7 +18,7 @@
  */
 package org.apache.felix.ipojo.parser;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.StringTokenizer;
 
@@ -27,7 +27,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ParseUtils {
+public final class ParseUtils {
 
     /**
      * Parse the string form of an array as {a, b, c}.
@@ -37,18 +37,13 @@
      */
     public static String[] parseArrays(String str) {
         // Remove { and }
-        if (str.startsWith("{") && str.endsWith("}")) {
-            String m = str.substring(1, str.length() - 1);
+        if (str.charAt(0) == '{' && str.charAt(str.length() - 1) == '}') {
+            String internal = (str.substring(1, str.length() - 1)).trim();
             // Check empty array
-            m = m.trim();
-            if (m.length() == 0) {
+            if (internal.length() == 0) {
                 return new String[0];
             }
-            String[] values = split(m, ",");
-            for (int i = 0; i < values.length; i++) {
-                values[i] = values[i].trim();
-            }
-            return values;
+            return split(internal, ",");
         } else {
             return new String[] { str };
         }
@@ -61,40 +56,24 @@
      * @return the resulting string array
      */
     public static List parseArraysAsList(String str) {
-        List result = new ArrayList();
-        // Remove { and }
-        if (str.startsWith("{") && str.endsWith("}")) {
-            String m = str.substring(1, str.length() - 1);
-            // Check empty array
-            m = m.trim();
-            if (m.length() == 0) {
-                return result;
-            }
-            String[] values = split(m, ",");
-            for (int i = 0; i < values.length; i++) {
-                result.add(values[i].trim());
-            }
-            return result;
-        } else {
-            result.add(str);
-            return result;
-        }
+        return Arrays.asList(parseArrays(str));
     }
     
     /**
      * Split method. 
      * This method is equivalent of the String.split in java 1.4
+     * The result array contains 'trimmed' String
      * @param toSplit : String to split
      * @param separator : separator
      * @return the token array 
      */
     public static String[] split(String toSplit, String separator) {
-        StringTokenizer st = new StringTokenizer(toSplit, separator);
-        String[] result = new String[st.countTokens()];
-        int i = 0;
-        while (st.hasMoreElements()) {
-            result[i] = st.nextToken();
-            i++;
+        StringTokenizer tokenizer = new StringTokenizer(toSplit, separator);
+        String[] result = new String[tokenizer.countTokens()];
+        int index = 0;
+        while (tokenizer.hasMoreElements()) {
+            result[index] = tokenizer.nextToken().trim();
+            index++;
         }
         return result;
     }
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/PojoMetadata.java
similarity index 82%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
index 3d08854..ee8c6fc 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/PojoMetadata.java
@@ -26,7 +26,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ManipulationMetadata {
+public class PojoMetadata {
     
     /**
      * List of implemented interfaces.
@@ -55,21 +55,21 @@
      * parsing manipulation metadata.
      * @param metadata : component type metadata
      */
-    public ManipulationMetadata(Element metadata) {
+    public PojoMetadata(Element metadata) {
         Element manip = metadata.getElements("manipulation", "")[0];
         m_super = manip.getAttribute("super");
         Element[] fields = manip.getElements("field");
-        for (int i = 0; i < fields.length; i++) {
-            FieldMetadata fm = new FieldMetadata(fields[i]);
-            addField(fm);
+        for (int i = 0; fields != null && i < fields.length; i++) {
+            FieldMetadata field = new FieldMetadata(fields[i]);
+            addField(field);
         }
         Element[] methods = manip.getElements("method");
-        for (int i = 0; i < methods.length; i++) {
-            MethodMetadata fm = new MethodMetadata(methods[i]);
-            addMethod(fm);
+        for (int i = 0; methods != null && i < methods.length; i++) {
+            MethodMetadata method = new MethodMetadata(methods[i]);
+            addMethod(method);
         }
         Element[] itfs = manip.getElements("interface");
-        for (int i = 0; i < itfs.length; i++) {
+        for (int i = 0; itfs != null && i < itfs.length; i++) {
             addInterface(itfs[i].getAttribute("name"));
         }
     }
@@ -167,13 +167,13 @@
     public MethodMetadata getMethod(String name, String[] types) {
         for (int i = 0; i < m_methods.length; i++) {
             if (m_methods[i].getMethodName().equalsIgnoreCase(name) && m_methods[i].getMethodArguments().length == types.length) {
-                boolean ok = true;
-                for (int j = 0; ok && j < types.length; j++) {
-                    if (! types[j].equals(m_methods[i].getMethodArguments()[j])) {
-                        ok = false;
+                int argIndex = 0;
+                for (; argIndex < types.length; argIndex++) {
+                    if (! types[argIndex].equals(m_methods[i].getMethodArguments()[argIndex])) {
+                        break;
                     }
                 }
-                if (ok) { return m_methods[i]; }
+                if (argIndex == types.length) { return m_methods[i]; } // No mismatch detected.
             }
         }
         return null;
@@ -181,11 +181,11 @@
         
      /**
       * Add a method to the list.
-     * @param mm : Method Metadata to add.
+     * @param method : Method Metadata to add.
      */
-    private void addMethod(MethodMetadata mm) {
+    private void addMethod(MethodMetadata method) {
         for (int i = 0; (m_methods != null) && (i < m_methods.length); i++) {
-            if (m_methods[i] == mm) {
+            if (m_methods[i] == method) {
                 return;
             }
         }
@@ -193,20 +193,20 @@
         if (m_methods.length > 0) {
             MethodMetadata[] newInstances = new MethodMetadata[m_methods.length + 1];
             System.arraycopy(m_methods, 0, newInstances, 0, m_methods.length);
-            newInstances[m_methods.length] = mm;
+            newInstances[m_methods.length] = method;
             m_methods = newInstances;
         } else {
-            m_methods = new MethodMetadata[] { mm };
+            m_methods = new MethodMetadata[] { method };
         }
     }
         
      /**
       * Add a field to the list.
-     * @param mm : the Field Metadata to add.
+     * @param field : the Field Metadata to add.
      */
-    private void addField(FieldMetadata mm) {
+    private void addField(FieldMetadata field) {
         for (int i = 0; (m_fields != null) && (i < m_fields.length); i++) {
-            if (m_fields[i] == mm) {
+            if (m_fields[i] == field) {
                 return;
             }
         }
@@ -214,20 +214,20 @@
         if (m_fields.length > 0) {
             FieldMetadata[] newInstances = new FieldMetadata[m_fields.length + 1];
             System.arraycopy(m_fields, 0, newInstances, 0, m_fields.length);
-            newInstances[m_fields.length] = mm;
+            newInstances[m_fields.length] = field;
             m_fields = newInstances;
         } else {
-            m_fields = new FieldMetadata[] { mm };
+            m_fields = new FieldMetadata[] { field };
         }
     }
         
     /**
      * Add the interface to the list.
-     * @param mm : the interface name to add.
+     * @param itf : the interface name to add.
      */
-    private void addInterface(String mm) {
+    private void addInterface(String itf) {
         for (int i = 0; (m_interfaces != null) && (i < m_interfaces.length); i++) {
-            if (m_interfaces[i] == mm) {
+            if (m_interfaces[i] == itf) {
                 return;
             }
         }
@@ -235,10 +235,10 @@
         if (m_interfaces.length > 0) {
             String[] newInstances = new String[m_interfaces.length + 1];
             System.arraycopy(m_interfaces, 0, newInstances, 0, m_interfaces.length);
-            newInstances[m_interfaces.length] = mm;
+            newInstances[m_interfaces.length] = itf;
             m_interfaces = newInstances;
         } else {
-            m_interfaces = new String[] { mm };
+            m_interfaces = new String[] { itf };
         }
     }
 
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 f19373c..a17326d 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
@@ -22,15 +22,15 @@
 import java.lang.reflect.Method;
 
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.parser.FieldMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
 
 /**
  * A callback allows calling a method on the component instances.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Callback {
-    
+
     /**
      * Method object.
      */
@@ -50,7 +50,7 @@
      * Reference on the instance manager.
      */
     private InstanceManager m_manager;
-    
+
     /**
      * Argument classes.
      */
@@ -58,193 +58,112 @@
 
     /**
      * Callback constructor.
-     * 
      * @param method : the name of the method to call
      * @param args : argument type name
      * @param isStatic : is the method a static method
-     * @param im : the instance manager of the component containing the method
+     * @param manager : the instance manager of the component containing the method
      */
-    public Callback(String method, String[] args, boolean isStatic, InstanceManager im) {
+    public Callback(String method, String[] args, boolean isStatic, InstanceManager manager) {
         m_method = method;
         m_isStatic = isStatic;
-        m_manager = im;
+        m_manager = manager;
         if (args != null) {
-            m_args = new String[args.length];
-            for (int i = 0; i < args.length; i++) {
-                // Primitive Array 
-                if (args[i].endsWith("[]") && args[i].indexOf(".") == -1) {
-                    String arr = "";
-                    for (int j = 0; j < args[i].length(); j++) {
-                        if (args[i].charAt(j) == '[') { arr += '['; }
-                    }
-                    int index = args[i].indexOf('[');
-                    m_args[i] = arr + getInternalPrimitiveType(args[i].substring(0, index));
-                }
-                // Non-Primitive Array 
-                if (args[i].endsWith("[]") && args[i].indexOf(".") != -1) {
-                    String arr = "";
-                    for (int j = 0; j < args[i].length(); j++) {
-                        if (args[i].charAt(j) == '[') { arr += '['; }
-                    }
-                    int index = args[i].indexOf('[');
-                    m_args[i] = arr + "L" + args[i].substring(0, index) + ";";
-                }
-                // Simple type 
-                if (!args[i].endsWith("[]")) {
-                    m_args[i] = args[i];
-                }
-            }
+            computeArguments(args);
         }
-        
     }
-    
+
     /**
      * Callback constructor.
-     * 
      * @param method : the name of the method to call
      * @param args : argument classes
      * @param isStatic : is the method a static method
-     * @param im : the instance manager of the component containing the method
+     * @param manager : the instance manager of the component containing the method
      */
-    public Callback(String method, Class[] args, boolean isStatic, InstanceManager im) {
+    public Callback(String method, Class[] args, boolean isStatic, InstanceManager manager) {
         m_method = method;
         m_isStatic = isStatic;
-        m_manager = im;
+        m_manager = manager;
         m_args = new String[args.length];
         for (int i = 0; i < args.length; i++) {
             m_args[i] = args[i].getName();
         }
     }
-    
+
     /**
      * Constructor.
-     * @param mm : Method Metadata obtain form manipulation metadata.
-     * @param im : instance manager.
+     * @param method : Method Metadata obtain form manipulation metadata.
+     * @param manager : instance manager.
      */
-    public Callback(MethodMetadata mm, InstanceManager im) {
+    public Callback(MethodMetadata method, InstanceManager manager) {
         m_isStatic = false;
-        m_method = mm.getMethodName();
-        m_manager = im;
-        String[] args = mm.getMethodArguments();
+        m_method = method.getMethodName();
+        m_manager = manager;
+        computeArguments(method.getMethodArguments());
+    }
+
+    /**
+     * Compute arguments of the method.
+     * @param args : arguments of the method.
+     */
+    private void computeArguments(String[] args) {
         m_args = new String[args.length];
         for (int i = 0; i < args.length; i++) {
-            // Primitive Array 
-            if (args[i].endsWith("[]") && args[i].indexOf(".") == -1) {
-                String arr = "";
-                for (int j = 0; j < args[i].length(); j++) {
-                    if (args[i].charAt(j) == '[') { arr += '['; }
-                }
-                int index = args[i].indexOf('[');
-                m_args[i] = arr + getInternalPrimitiveType(args[i].substring(0, index));
-            }
-            // Non-Primitive Array 
-            if (args[i].endsWith("[]") && args[i].indexOf(".") != -1) {
-                String arr = "";
-                for (int j = 0; j < args[i].length(); j++) {
-                    if (args[i].charAt(j) == '[') { arr += '['; }
-                }
-                int index = args[i].indexOf('[');
-                m_args[i] = arr + "L" + args[i].substring(0, index) + ";";
-            }
-            // Simple type 
-            if (!args[i].endsWith("[]")) {
-                m_args[i] = args[i];
-            }
+            m_args[i] = FieldMetadata.getReflectionType(args[i]);
         }
     }
 
     /**
-     * Get the internal notation for primitive type.
-     * @param string : Stringform of the type
-     * @return the internal notation or null if not found
+     * Search the looked method in the given method arrays.
+     * @param methods : method array in which we need to look
+     * @return the method object or null if not found
      */
-    private String getInternalPrimitiveType(String string) {
-        if (string.equalsIgnoreCase("boolean")) {
-            return "Z";
-        }
-        if (string.equalsIgnoreCase("char")) {
-            return "C";
-        }
-        if (string.equalsIgnoreCase("byte")) {
-            return "B";
-        }
-        if (string.equalsIgnoreCase("short")) {
-            return "S";
-        }
-        if (string.equalsIgnoreCase("int")) {
-            return "I";
-        }
-        if (string.equalsIgnoreCase("float")) {
-            return "F";
-        }
-        if (string.equalsIgnoreCase("long")) {
-            return "J";
-        }
-        if (string.equalsIgnoreCase("double")) {
-            return "D";
-        }
-        return null;
-    }
-    
-    /**
-     * Search the method object in the POJO by analyzing present method.
-     * The name of the method and the argument type are checked.
-     */
-    protected void searchMethod() {
-        Method[] methods = m_manager.getClazz().getDeclaredMethods();
-        for (int i = 0; m_methodObj == null && i < methods.length; i++) {
+    private Method searchMethodInMethodArray(Method[] methods) {
+        for (int i = 0; i < methods.length; i++) {
             // First check the method name
             if (methods[i].getName().equals(m_method)) {
                 // Check arguments
                 Class[] clazzes = methods[i].getParameterTypes();
                 if (clazzes.length == m_args.length) { // Test size to avoid useless loop
-                    boolean ok = true;
-                    for (int j = 0; ok && j < m_args.length; j++) {
-                        if (!m_args[j].equals(clazzes[j].getName())) {
-                            ok = false;
+                    int argIndex = 0;
+                    for (; argIndex < m_args.length; argIndex++) {
+                        if (!m_args[argIndex].equals(clazzes[argIndex].getName())) {
+                            break;
                         }
                     }
-                    if (ok) {
-                        m_methodObj = methods[i]; // It is the looked method.
-                    } 
+                    if (argIndex == m_args.length) { // No mismatch detected. 
+                        return methods[i]; // It is the looked method.
+                    }
                 }
+            }
+        }
+        return null;
+    }
 
-            }
-        }
-        
-        if (m_methodObj == null) { //look at parent classes
+    /**
+     * Search the method object in the POJO by analyzing present method. The name of the method and the argument type are checked.
+     * @throws NoSuchMethodException : occurs when the method cannot be found either in the pojo class either in parent classes.
+     */
+    protected void searchMethod() throws NoSuchMethodException {
+        Method[] methods = m_manager.getClazz().getDeclaredMethods();
+        m_methodObj = searchMethodInMethodArray(methods);
+
+        if (m_methodObj == null) { // look at parent classes
             methods = m_manager.getClazz().getMethods();
-            for (int i = 0; m_methodObj == null && i < methods.length; i++) {
-                // First check the method name
-                if (methods[i].getName().equals(m_method)) {
-                    // Check arguments
-                    Class[] clazzes = methods[i].getParameterTypes();
-                    if (clazzes.length == m_args.length) { // Test size to avoid useless loop
-                        boolean ok = true;
-                        for (int j = 0; ok && j < m_args.length; j++) {
-                            if (!m_args[j].equals(clazzes[j].getName())) {
-                                ok = false;
-                            }
-                        }
-                        if (ok) {
-                            m_methodObj = methods[i]; // It is the looked method.
-                        } 
-                    }
-                }
-            }
+            m_methodObj = searchMethodInMethodArray(methods);
         }
-        
+
         if (m_methodObj == null) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " cannot be called : method not found");
-            m_manager.stop();
+            throw new NoSuchMethodException(m_method);
         } else {
-            m_methodObj.setAccessible(true);
+            if (! m_methodObj.isAccessible()) { 
+                // If not accessible, try to set the accessibility.
+                m_methodObj.setAccessible(true);
+            }
         }
     }
 
     /**
      * Call the method.
-     * 
      * @return the result of the invocation, null for void method, the last result for multi-object instance
      * @throws NoSuchMethodException : Method is not found in the class
      * @throws InvocationTargetException : The method is not static
@@ -256,7 +175,6 @@
 
     /**
      * Call the current callback method on the instance given in parameter.
-     * 
      * @param instance : instance on which call the callback
      * @return the result of the invocation, null for void method
      * @throws NoSuchMethodException : the method was not found
@@ -269,19 +187,17 @@
 
     /**
      * Call the callback on the method with the argument given in parameter.
-     * 
      * @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 callback method cannot be called
-     * @throws InvocationTargetException : an error occurs inside the called
-     * method
+     * @throws InvocationTargetException : an error occurs inside the called method
      */
     public Object call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
         if (m_methodObj == null) {
             searchMethod();
         }
-        
+
         if (m_isStatic) {
             return m_methodObj.invoke(null, arg);
         } else {
@@ -291,35 +207,32 @@
             if (m_manager.getPojoObjects() == null) {
                 return m_methodObj.invoke(m_manager.getPojoObject(), arg);
             } else {
-                Object r = null;
+                Object newObject = null;
                 for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
-                    r = m_methodObj.invoke(m_manager.getPojoObjects()[i], arg);
+                    newObject = m_methodObj.invoke(m_manager.getPojoObjects()[i], arg);
                 }
-                return r;
+                return newObject;
             }
         }
     }
 
     /**
-     * Call the callback on the method with the argument given in parameter and
-     * with the arguments given in parameter too.
-     * 
+     * Call the callback on the method with the argument given in parameter and with the arguments given in parameter too.
      * @param instance : instance on which call the callback
      * @param arg : the argument array
      * @return the result of the invocation, null for void method
      * @throws NoSuchMethodException : the callback method is not found
      * @throws IllegalAccessException : the callback method cannot be called
-     * @throws InvocationTargetException : an error occurs inside the called
-     * method
+     * @throws InvocationTargetException : an error occurs inside the called method
      */
     public Object call(Object instance, Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
         if (m_methodObj == null) {
             searchMethod();
         }
-        
+
         return m_methodObj.invoke(instance, arg);
     }
-    
+
     public String getMethod() {
         return m_method;
     }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
new file mode 100644
index 0000000..d644805
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
@@ -0,0 +1,792 @@
+/* 
+ * 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.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Abstract dependency model. This class is the parent class of every service dependency. It manages the most part of dependency management. This
+ * class creates an insterface between the service tracker and the concrete dependency.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class DependencyModel implements TrackerCustomizer {
+
+    /**
+     * Dependency state : BROKEN. A broken dependency cannot be fulfilled anymore. The dependency becomes broken when a used service disappears in the
+     * static binding policy.
+     */
+    public static final int BROKEN = -1;
+
+    /**
+     * Dependency state : UNRESOLVED. A dependency is unresolved if the dependency is not valid and no service providers are available.
+     */
+    public static final int UNRESOLVED = 0;
+
+    /**
+     * Dependency state : RESOLVED. A dependency is resolved if the dependency is optional or at least one provider is available.
+     */
+    public static final int RESOLVED = 1;
+
+    /**
+     * Binding policy : Dynamic. In this policy, services can appears and departs without special treatment.
+     */
+    public static final int DYNAMIC_BINDING_POLICY = 0;
+
+    /**
+     * Binding policy : Static. Once a service is used, if this service disappears the dependency becomes BROKEN. The instance needs to be recreated.
+     */
+    public static final int STATIC_BINDING_POLICY = 1;
+
+    /**
+     * Binding policy : Dynamic-Priority. In this policy, services can appears and departs. However, once a service with a highest ranking (according
+     * to the used comparator) appears, this new service is re-injected.
+     */
+    public static final int DYNAMIC_PRIORITY_BINDING_POLICY = 2;
+
+    /**
+     * Does the dependency bind several providers ?
+     */
+    private boolean m_aggregate;
+
+    /**
+     * Is the dependency optional ?
+     */
+    private boolean m_optional;
+
+    /**
+     * Required specification. Cannot change once set.
+     */
+    private Class m_specification;
+
+    /**
+     * Comparator to sort service references.
+     */
+    private Comparator m_comparator;
+
+    /**
+     * LDAP filter object selecting service references form the set of providers providing the required specification.
+     */
+    private Filter m_filter;
+
+    /**
+     * Bundle context used by the dependency. (could be a service context).
+     */
+    private BundleContext m_context;
+
+    /**
+     * Listener object on which invoking the validate and invalidate methods.
+     */
+    private final DependencyStateListener m_listener;
+
+    /**
+     * Actual state of the dependency.
+     */
+    private int m_state;
+
+    /**
+     * Binding policy of the dependency.
+     */
+    private int m_policy = DYNAMIC_BINDING_POLICY; // Is notas we have to handler policy change in a future version.
+
+    /**
+     * Service tracker used by this dependency.
+     */
+    private Tracker m_tracker;
+
+    /**
+     * List of matching service references. This list is a subset of tracked references. This set is compute according to the filter and the match
+     * method.
+     */
+    private final List m_matchingRefs = new ArrayList();
+
+    /**
+     * Constructor.
+     * @param specification : required specification
+     * @param aggregate : is the dependency aggregate ?
+     * @param optional : is the dependency optional ?
+     * @param filter : LDAP filter
+     * @param comparator : comparator object to sort references
+     * @param policy : binding policy
+     * @param context : bundle context (or service context)
+     * @param listener : dependency lifecycle listener to notify from dependency state changes.
+     */
+    public DependencyModel(Class specification, boolean aggregate, boolean optional, Filter filter, Comparator comparator, int policy,
+            BundleContext context, DependencyStateListener listener) {
+        m_specification = specification;
+        m_aggregate = aggregate;
+        m_optional = optional;
+        m_filter = filter;
+        m_comparator = comparator;
+        m_context = context;
+        m_policy = policy;
+        // If the dynamic priority policy is chosen, and we have no comparator, fix it to OSGi standard service reference comparator.
+        if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && m_comparator == null) {
+            m_comparator = new ServiceReferenceRankingComparator();
+        }
+        m_state = UNRESOLVED;
+        m_listener = listener;
+    }
+
+    /**
+     * Open the tracking.
+     */
+    public void start() {
+        m_tracker = new Tracker(m_context, m_specification.getName(), this);
+        m_tracker.open();
+        computeDependencyState();
+    }
+
+    /**
+     * Close the tracking.
+     */
+    public void stop() {
+        if (m_tracker != null) {
+            m_tracker.close();
+            m_tracker = null;
+        }
+        m_state = UNRESOLVED;
+    }
+
+    /**
+     * Is the reference set frozen (cannot change anymore) ? This method must be override by concrete dependency to support the static binding policy.
+     * This method is just used by default. The method must always return false for non-static dependency.
+     * @return true if the reference set is frozen.
+     */
+    public boolean isFrozen() {
+        return false;
+    }
+
+    /**
+     * Does the service reference match ? This method must be override by concrete dependency if they need to advanced testing on service reference
+     * (that cannot be express in the LDAP filter). By default this method return true.
+     * @param ref : tested reference.
+     * @return true
+     */
+    public boolean match(ServiceReference ref) {
+        return true;
+    }
+
+    /**
+     * Compute the actual dependency state.
+     */
+    private void computeDependencyState() {
+        if (m_state == BROKEN) { return; } // The dependency is broken ...
+
+        boolean mustCallValidate = false;
+        boolean mustCallInvalidate = false;
+        synchronized (this) {
+            if (m_optional || !m_matchingRefs.isEmpty()) {
+                // The dependency is valid
+                if (m_state == UNRESOLVED) {
+                    m_state = RESOLVED;
+                    mustCallValidate = true;
+                }
+            } else {
+                // The dependency is invalid
+                if (m_state == RESOLVED) {
+                    m_state = UNRESOLVED;
+                    mustCallInvalidate = true;
+                }
+            }
+        }
+
+        // Invoke callback in a non-synchronized region
+        if (mustCallInvalidate) {
+            invalidate();
+        } else if (mustCallValidate) {
+            validate();
+        }
+
+    }
+
+    /**
+     * Service tracker adding service callback. We accept the service only if we aren't broken or frozen.
+     * @param ref : the new dependency.
+     * @return true if the reference must be tracked.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference ref) {
+        return !((m_state == BROKEN) || isFrozen());
+    }
+
+    /**
+     * Service Tracker added service callback. If the service matches, manage the arrival.
+     * @param ref : new references.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference ref) {
+        if ((m_filter == null || m_filter.match(ref)) && match(ref)) {
+            manageArrival(ref);
+        }
+        // Do not store the service if it doesn't match.
+    }
+
+    /**
+     * Manage the arrival of a new service reference. The reference is valid and match the filter and the match method. This method has different
+     * behavior according to the binding policy.
+     * @param ref : the new reference
+     */
+    private void manageArrival(ServiceReference ref) {
+
+        // Create a local copy of the state and of the list size.
+        int state = m_state;
+        int size;
+
+        synchronized (this) {
+            m_matchingRefs.add(ref);
+
+            // Sort the collection if needed.
+            if (m_comparator != null) {
+                Collections.sort(m_matchingRefs, m_comparator);
+            }
+
+            size = m_matchingRefs.size();
+        }
+
+        if (m_aggregate) {
+            onServiceArrival(ref); // Always notify the arrival for aggregate dependencies.
+            if (state == UNRESOLVED) { // If we was unresolved, try to validate the dependency.
+                computeDependencyState();
+            }
+        } else { // We are not aggregate.
+            if (size == 1) {
+                onServiceArrival(ref); // It is the first service, so notify.
+                computeDependencyState();
+            } else {
+                // In the case of a dynamic priority binding, we have to test if we have to update the bound reference
+                if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && m_matchingRefs.get(0) == ref) {
+                    // We are sure that we have at least two references, so if the highest ranked references (first one) is the new received
+                    // references,
+                    // we have to unbind the used one and to bind the the new one.
+                    onServiceDeparture((ServiceReference) m_matchingRefs.get(1));
+                    onServiceArrival(ref);
+                }
+            }
+        }
+        // Ignore others cases
+    }
+
+    /**
+     * Service tracker removed service callback. A service goes away. The depart need to be managed only if the reference was used.
+     * @param ref : leaving service reference
+     * @param arg1 : service object if the service was get
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference ref, Object arg1) {
+        if (m_matchingRefs.contains(ref)) {
+            manageDeparture(ref, arg1);
+        }
+    }
+
+    /**
+     * Manage the departure of a used service.
+     * @param ref : leaving service reference
+     * @param obj : service object if the service was get
+     */
+    private void manageDeparture(ServiceReference ref, Object obj) {
+        // If we already get this service and the binding policy is static, the dependency becomes broken
+        if (isFrozen() && obj != null) {
+            if (m_state != BROKEN) {
+                m_state = BROKEN;
+                invalidate();
+            }
+        } else {
+            synchronized (this) {
+                m_matchingRefs.remove(ref);
+            }
+            if (obj == null) {
+                computeDependencyState(); // check if the dependency stills valid.
+            } else {
+                onServiceDeparture(ref);
+                ServiceReference newRef = getServiceReference();
+                if (newRef == null) { // Check if there is another provider.
+                    computeDependencyState(); // no more references.
+                } else {
+                    if (!m_aggregate) {
+                        onServiceArrival(newRef); // Injecting the new service reference for non aggregate dependencies.
+                    }
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Service tracker modified service callback. This method must handle if the modified service should be considered as a depart or an arrival.
+     * According to the dependency filter, a service can now match or can no match anymore.
+     * @param ref : modified reference
+     * @param arg1 : service object if already get.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference ref, Object arg1) {
+        if (m_matchingRefs.contains(ref)) {
+            // It's a used service. Check if the service always match.
+            if (!(m_filter == null || m_filter.match(ref)) && match(ref)) {
+                // The service does not match anymore. Call removedService.
+                manageDeparture(ref, arg1);
+            } else {
+                onServiceModification(ref);
+            }
+        } else {
+            // The service was not used. Check if it matches.
+            if ((m_filter == null || m_filter.match(ref)) && match(ref)) {
+                manageArrival(ref);
+            }
+            // Else, the service does not match.
+        }
+    }
+
+    /**
+     * Get the next matching service reference.
+     * @return null if no more provider is available, else return the first reference from the matching set.
+     */
+    public ServiceReference getServiceReference() {
+        synchronized (this) {
+            if (m_matchingRefs.isEmpty()) {
+                return null;
+            } else {
+                return (ServiceReference) m_matchingRefs.get(0);
+            }
+        }
+    }
+
+    /**
+     * Get matching service references.
+     * @return the sorted (if a comparator is used) array of matching service references, null if no references are available.
+     */
+    public ServiceReference[] getServiceReferences() {
+        synchronized (this) {
+            if (m_matchingRefs.isEmpty()) { return null; }
+            return (ServiceReference[]) m_matchingRefs.toArray(new ServiceReference[m_matchingRefs.size()]);
+        }
+    }
+
+    /**
+     * Get the list of currently used service references.
+     * @return the list of used reference (according to the service tracker).
+     */
+    public List getUsedServiceReferences() {
+        synchronized (this) {
+            // The list must confront actual matching services with already get services from the tracker.
+
+            int size = m_matchingRefs.size();
+            List usedByTracker = m_tracker.getUsedServiceReferences();
+            if (size == 0 || usedByTracker == null) { return null; }
+
+            List list = new ArrayList(1);
+            for (int i = 0; i < size; i++) {
+                if (usedByTracker.contains(m_matchingRefs.get(i))) {
+                    list.add(m_matchingRefs.get(i)); // Add the service in the list.
+                    if (!isAggregate()) { // IF we are not multiple, return the list when the first element is found.
+                        return list;
+                    }
+                }
+            }
+
+            return list;
+        }
+    }
+
+    /**
+     * Get the number of actual matching references.
+     * @return the number of matching references
+     */
+    public int getSize() {
+        return m_matchingRefs.size();
+    }
+
+    /**
+     * Concrete dependency callback. This method is called when a new service need to be re-injected in the underlying concrete dependency.
+     * @param ref : service reference to inject.
+     */
+    public abstract void onServiceArrival(ServiceReference ref);
+
+    /**
+     * Concrete dependency callback. This method is called when a used service (already injected) is leaving.
+     * @param ref : the leaving service reference.
+     */
+    public abstract void onServiceDeparture(ServiceReference ref);
+
+    /**
+     * This method can be override by the concrete dependency to be notified of service modification. This modification is not an arrival or a
+     * departure.
+     * @param ref : modified service reference.
+     */
+    public void onServiceModification(ServiceReference ref) {
+        // Do nothing by default.
+    }
+
+    /**
+     * Concrete dependency callback. This method is called when the dependency is reconfigured and when this reconfiguration implies changes on the
+     * matching service set ( and by the way on the injected service).
+     * @param departs : service leaving the matching set.
+     * @param arrivals : service arriving in the matching set.
+     */
+    public abstract void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals);
+
+    /**
+     * Call the listener callback to notify the new state of the current dependency.
+     */
+    private void invalidate() {
+        m_listener.invalidate(this);
+    }
+
+    /**
+     * Call the listener callback to notify the new state of the current dependency.
+     */
+    private void validate() {
+        m_listener.validate(this);
+    }
+
+    /**
+     * Get the actual state of the dependency.
+     * @return : the state of the dependency.
+     */
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * Get the tracked specification.
+     * @return the Class object tracked by the dependency.
+     */
+    public Class getSpecification() {
+        return m_specification;
+    }
+
+    /**
+     * Set the required specification of this service dependency. This operation is not supported if the dependency tracking has already begun.
+     * @param specification : required specification.
+     */
+    public void setSpecification(Class specification) {
+        if (m_tracker == null) {
+            m_specification = specification;
+        } else {
+            throw new UnsupportedOperationException("Dynamic specification change is not yet supported");
+        }
+    }
+
+    /**
+     * Set the filter of the dependency. This method recompute the matching set and call the onDependencyReconfiguration callback.
+     * @param filter : new LDAP filter.
+     */
+    public void setFilter(Filter filter) { //NOPMD
+        m_filter = filter;
+        if (m_tracker != null) { // Tracking started ...
+            List toRemove = new ArrayList();
+            List toAdd = new ArrayList();
+            ServiceReference usedRef = null;
+            synchronized (this) {
+
+                // Store the used service references.
+                if (!m_aggregate && !m_matchingRefs.isEmpty()) {
+                    usedRef = (ServiceReference) m_matchingRefs.get(0);
+                }
+
+                // Get actually all tracked references.
+                ServiceReference[] refs = m_tracker.getServiceReferences();
+
+                if (refs == null) {
+                    for (int j = 0; j < m_matchingRefs.size(); j++) {
+                        // All references need to be removed.
+                        toRemove.add(m_matchingRefs.get(j));
+                    }
+                    // No more matching dependency. Clear the matching reference set.
+                    m_matchingRefs.clear();
+                } else {
+                    // Compute matching services.
+                    List matching = new ArrayList();
+                    for (int i = 0; i < refs.length; i++) {
+                        if (m_filter == null || m_filter.match(refs[i]) && match(refs[i])) {
+                            matching.add(refs[i]);
+                        }
+                    }
+                    // Now compare with used services.
+                    for (int j = 0; j < m_matchingRefs.size(); j++) {
+                        ServiceReference ref = (ServiceReference) m_matchingRefs.get(j);
+                        // Check if the reference is inside the matching list:
+                        if (!matching.contains(ref)) {
+                            // The reference should be removed
+                            toRemove.add(ref);
+                        }
+                    }
+
+                    // Then remove services which do no more match.
+                    m_matchingRefs.removeAll(toRemove);
+
+                    // Then, add new matching services.
+
+                    for (int k = 0; k < matching.size(); k++) {
+                        if (!m_matchingRefs.contains(matching.get(k))) {
+                            m_matchingRefs.add(matching.get(k));
+                            toAdd.add(matching.get(k));
+                        }
+                    }
+
+                    // Sort the collections if needed.
+                    if (m_comparator != null) {
+                        Collections.sort(m_matchingRefs, m_comparator);
+                        Collections.sort(toAdd, m_comparator);
+                        Collections.sort(toRemove, m_comparator);
+                    }
+
+                }
+            }
+
+            // Call the callback outside the sync bloc.
+            if (m_aggregate) {
+                ServiceReference[] rem = null;
+                ServiceReference[] add = null;
+                if (!toAdd.isEmpty()) {
+                    add = (ServiceReference[]) toAdd.toArray(new ServiceReference[toAdd.size()]);
+                }
+                if (!toRemove.isEmpty()) {
+                    rem = (ServiceReference[]) toRemove.toArray(new ServiceReference[toRemove.size()]);
+                }
+                if (rem != null || add != null) { // Notify the change only when a change is made on the matching reference list.
+                    onDependencyReconfiguration(rem, add);
+                }
+            } else {
+                // Create a local copy to avoid un-sync reference list access.
+                int size;
+                ServiceReference newRef = null;
+                synchronized (m_matchingRefs) {
+                    size = m_matchingRefs.size();
+                    if (size > 0) {
+                        newRef = (ServiceReference) m_matchingRefs.get(0);
+                    }
+                }
+                // Non aggregate case.
+                // If the used reference was not null
+                if (usedRef == null) {
+                    // The used ref was null,
+                    if (size > 0) {
+                        onDependencyReconfiguration(null, new ServiceReference[] { newRef });
+                    } // Don't notify the change, if the set is not touched by the reconfiguration.
+                } else {
+                    // If the used ref disappears, inject a new service if available, else reinject null.
+                    if (toRemove.contains(usedRef)) {
+                        // We have to replace the service.
+                        if (size > 0) {
+                            onDependencyReconfiguration(new ServiceReference[] { usedRef }, new ServiceReference[] { newRef });
+                        } else {
+                            onDependencyReconfiguration(new ServiceReference[] { usedRef }, null);
+                        }
+                    } else if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && newRef != usedRef) { //NOPMD
+                        // In the case of dynamic-priority, check if the used ref is no more the highest reference
+                        onDependencyReconfiguration(new ServiceReference[] { usedRef }, new ServiceReference[] { newRef });
+                    }
+                }
+            }
+            // Now, compute the new dependency state.
+            computeDependencyState();
+        }
+    }
+
+    /**
+     * Return the dependency filter (String form).
+     * @return the String form of the LDAP filter used by this dependency, null if not set.
+     */
+    public String getFilter() {
+        if (m_filter == null) {
+            return null;
+        } else {
+            return m_filter.toString();
+        }
+    }
+
+    /**
+     * Set the aggregate attribute of the current dependency. If the tracking is open, it will call arrival and departure callbacks.
+     * @param isAggregate : new aggregate attribute value.
+     */
+    public synchronized void setAggregate(boolean isAggregate) {
+        if (m_tracker == null) { // Not started ...
+            m_aggregate = isAggregate;
+        } else {
+            // We become aggregate.
+            if (!m_aggregate && isAggregate) {
+                m_aggregate = true;
+                // Call the callback on all non already injected service.
+                if (m_state == RESOLVED) {
+
+                    for (int i = 1; i < m_matchingRefs.size(); i++) { // The loop begin at 1, as the 0 is already injected.
+                        onServiceArrival((ServiceReference) m_matchingRefs.get(i));
+                    }
+                }
+            } else if (m_aggregate && !isAggregate) {
+                m_aggregate = false;
+                // We become non-aggregate.
+                if (m_state == RESOLVED) {
+                    for (int i = 1; i < m_matchingRefs.size(); i++) { // The loop begin at 1, as the 0 stills injected.
+                        onServiceDeparture((ServiceReference) m_matchingRefs.get(i));
+                    }
+                }
+            }
+            // Else, do nothing.
+        }
+    }
+
+    public boolean isAggregate() {
+        return m_aggregate;
+    }
+
+    /**
+     * Set the optionality attribute of the current dependency.
+     * @param isOptional : the new optional attribute value.
+     */
+    public void setOptionality(boolean isOptional) {
+        if (m_tracker == null) { // Not started ...
+            m_optional = isOptional;
+        } else {
+            computeDependencyState();
+        }
+    }
+
+    public boolean isOptional() {
+        return m_optional;
+    }
+
+    /**
+     * Return the used binding policy.
+     * @return the current binding policy.
+     */
+    public int getBindingPolicy() {
+        return m_policy;
+    }
+
+    /**
+     * Set the binding policy. Not yet supported.
+     */
+    public void setBindingPolicy() {
+        throw new UnsupportedOperationException("Binding Policy change is not yet supported");
+        // TODO supporting dynamic policy change.
+    }
+
+    public void setComparator(Comparator cmp) {
+        m_comparator = cmp;
+        // NOTE: the array will be sorted at the next get.
+    }
+
+    /**
+     * Set the bundle context used by this dependency. This operation is not supported if the tracker is already opened.
+     * @param context : bundle context or service context to use
+     */
+    public void setBundleContext(BundleContext context) {
+        if (m_tracker == null) { // Not started ...
+            m_context = context;
+        } else {
+            throw new UnsupportedOperationException("Dynamic bundle (i.e. service) context change is not supported");
+        }
+    }
+
+    /**
+     * Get a service object for the given reference.
+     * @param ref : wanted service reference
+     * @return : the service object attached to the given reference
+     */
+    public Object getService(ServiceReference ref) {
+        return m_tracker.getService(ref);
+    }
+
+    /**
+     * Unget a used service reference.
+     * @param ref : reference to unget.
+     */
+    public void ungetService(ServiceReference ref) {
+        m_tracker.ungetService(ref);
+    }
+
+    /**
+     * Helper method parsing the comparator attribute and returning the comparator object. If the 'comparator' attribute is not set, this method
+     * returns null. If the 'comparator' attribute is set to 'osgi', this method returns the normal OSGi comparator. In other case, it tries to create
+     * an instance of the declared comparator class.
+     * @param dep : Element describing the dependency
+     * @param context : bundle context (to load the comparator class)
+     * @return the comparator object, null if not set.
+     * @throws ConfigurationException the comparator class cannot be load or the comparator cannot be instantiated correctly.
+     */
+    public static Comparator getComparator(Element dep, BundleContext context) throws ConfigurationException {
+        Comparator cmp = null;
+        String comp = dep.getAttribute("comparator");
+        if (comp != null) {
+            if (comp.equalsIgnoreCase("osgi")) {
+                cmp = new ServiceReferenceRankingComparator();
+            } else {
+                try {
+                    Class cla = context.getBundle().loadClass(comp);
+                    cmp = (Comparator) cla.newInstance();
+                } catch (ClassNotFoundException e) {
+                    throw new ConfigurationException("Cannot load a customized comparator : " + e.getMessage());
+                } catch (IllegalAccessException e) {
+                    throw new ConfigurationException("Cannot create a customized comparator : " + e.getMessage());
+                } catch (InstantiationException e) {
+                    throw new ConfigurationException("Cannot create a customized comparator : " + e.getMessage());
+                }
+            }
+        }
+        return cmp;
+    }
+
+    /**
+     * Load the given specification class.
+     * @param specification : specification class name to load
+     * @param context : bundle context
+     * @return : the class object for the given specification
+     * @throws ConfigurationException : the class cannot be loaded correctly.
+     */
+    public static Class loadSpecification(String specification, BundleContext context) throws ConfigurationException {
+        Class spec = null;
+        try {
+            spec = context.getBundle().loadClass(specification);
+        } catch (ClassNotFoundException e) {
+            throw new ConfigurationException("A required specification cannot be loaded : " + specification);
+        }
+        return spec;
+    }
+
+    /**
+     * Helper method parsing the binding policy. If the 'policy' attribute is not set in the dependency, the method returns the 'DYNAMIC BINDING
+     * POLICY'. Accepted policy values are : dynamic, dynamic-priority and static.
+     * @param dep : Element describing the dependency
+     * @return : the policy attached to this dependency
+     * @throws ConfigurationException : an unknown biding policy was described.
+     */
+    public static int getPolicy(Element dep) throws ConfigurationException {
+        String policy = dep.getAttribute("policy");
+        if (policy == null || policy.equalsIgnoreCase("dynamic")) {
+            return DYNAMIC_BINDING_POLICY;
+        } else if (policy.equalsIgnoreCase("dynamic-priority")) {
+            return DYNAMIC_PRIORITY_BINDING_POLICY;
+        } else if (policy.equalsIgnoreCase("static")) {
+            return STATIC_BINDING_POLICY;
+        } else {
+            throw new ConfigurationException("Binding policy unknown : " + policy);
+        }
+    }
+
+}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java
new file mode 100644
index 0000000..5131337
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java
@@ -0,0 +1,39 @@
+/* 
+ * 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;
+
+
+/**
+ * This interface allows a class to be notified of dependency state changes.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface DependencyStateListener {
+
+    /**
+     * The given dependency becomes valid.
+     * @param dependency : dependency becoming valid.
+     */
+    void validate(DependencyModel dependency);
+    
+    /**
+     * The given dependency becomes invalid.
+     * @param dependency : dependency becoming invalid.
+     */
+    void invalidate(DependencyModel dependency);
+}
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 30a33a2..c8b8c26 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
@@ -28,6 +28,11 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Logger {
+    
+    /**
+     * Ipojo default log level property.
+     */
+    public static final String IPOJO_LOG_LEVEL = "ipojo.log.level";
 
     /**
      * Log Level ERROR.
@@ -67,14 +72,24 @@
     /**
      * Constructor.
      * 
-     * @param bc : bundle context
+     * @param context : bundle context
      * @param name : name of the logger
      * @param level : trace level
      */
-    public Logger(BundleContext bc, String name, int level) {
+    public Logger(BundleContext context, String name, int level) {
         m_name = name;
         m_level = level;
-        m_context = bc;
+        m_context = context;
+    }
+    
+    /**
+     * Constructor.
+     * 
+     * @param context : bundle context
+     * @param name : name of the logger
+     */
+    public Logger(BundleContext context, String name) {
+        this(context, name, getDefaultLevel(context));
     }
 
     /**
@@ -85,7 +100,7 @@
      */
     public void log(int level, String msg) {
         if (m_level >= level) {
-            dispatch(level, msg, null);
+            dispatch(level, msg);
         }
     }
 
@@ -94,26 +109,21 @@
      * 
      * @param level : level of the message
      * @param msg : message to log
-     * @param ex : exception attached to the message
+     * @param exception : exception attached to the message
      */
-    public void log(int level, String msg, Throwable ex) {
+    public void log(int level, String msg, Throwable exception) {
         if (m_level >= level) {
-            dispatch(level, msg, ex);
+            dispatch(level, msg, exception);
         }
     }
-
+    
     /**
      * Internal log method.
      * 
      * @param level : level of the message.
      * @param msg : message to log
-     * @param ex : exception attached to the message
      */
-    private void dispatch(int level, String msg, Throwable ex) {
-        String s = msg;
-        if (ex != null) {
-            s += " (" + ex.getMessage() + ")";
-        }
+    private void dispatch(int level, String msg) {
         
         ServiceReference ref = m_context.getServiceReference(LogService.class.getName());
         LogService log = null;
@@ -124,35 +134,35 @@
         String message = null;
         switch (level) {
             case DEBUG:
-                message = "[" + m_name + "] DEBUG: " + s;
+                message = "[" + m_name + "] DEBUG: " + msg;
                 if (log != null) {
                     log.log(LogService.LOG_DEBUG, message);
                 }
-                System.err.println(message);
+                System.err.println(message); // NOPMD
                 break;
             case ERROR:
-                message = "[" + m_name + "] ERROR: " + s;
+                message = "[" + m_name + "] ERROR: " + msg;
                 if (log != null) {
                     log.log(LogService.LOG_ERROR, message);
                 }
-                System.err.println(message);
+                System.err.println(message); //NOPMD
                 break;
             case INFO:
-                message = "[" + m_name + "] INFO: " + s;
+                message = "[" + m_name + "] INFO: " + msg;
                 if (log != null) {
                     log.log(LogService.LOG_INFO, message);
                 }
-                System.err.println(message);
+                System.err.println(message); // NOPMD
                 break;
             case WARNING:
-                message = "[" + m_name + "] WARNING: " + s;
+                message = "[" + m_name + "] WARNING: " + msg;
                 if (log != null) {
                     log.log(LogService.LOG_WARNING, message);
                 }
-                System.err.println(message);
+                System.err.println(message); // NOPMD
                 break;
             default:
-                System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + s);
+                System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + msg); // NOPMD
                 break;
         }
         
@@ -160,4 +170,98 @@
             m_context.ungetService(ref);
         }
     }
+
+    /**
+     * Internal log method.
+     * 
+     * @param level : level of the message.
+     * @param msg : message to log
+     * @param exception : exception attached to the message
+     */
+    private void dispatch(int level, String msg, Throwable exception) {
+        
+        ServiceReference ref = m_context.getServiceReference(LogService.class.getName());
+        LogService log = null;
+        if (ref != null) {
+            log = (LogService) m_context.getService(ref);
+        }
+        
+        String message = null;
+        switch (level) {
+            case DEBUG:
+                message = "[" + m_name + "] DEBUG: " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_DEBUG, message, exception);
+                }
+                System.err.println(message); // NOPMD
+                exception.printStackTrace(); // NOPMD
+                break;
+            case ERROR:
+                message = "[" + m_name + "] ERROR: " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_ERROR, message, exception);
+                }
+                System.err.println(message); // NOPMD
+                exception.printStackTrace(System.err); // NOPMD
+                break;
+            case INFO:
+                message = "[" + m_name + "] INFO: " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_INFO, message, exception);
+                }
+                System.err.println(message); // NOPMD
+                exception.printStackTrace(System.err); // NOPMD
+                break;
+            case WARNING:
+                message = "[" + m_name + "] WARNING: " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_WARNING, message, exception);
+                }
+                System.err.println(message); // NOPMD
+                exception.printStackTrace(System.err); // NOPMD
+                break;
+            default:
+                System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + msg); // NOPMD
+                exception.printStackTrace(); // NOPMD
+                break;
+        }
+        
+        if (log != null) {
+            m_context.ungetService(ref);
+        }
+    }
+    
+    /**
+     * Get the default logger level.
+     * The property is searched inside the framework properties, the system properties,
+     * and in the manifest from the given bundle context. By default, set the level to WARNING. 
+     * @param context : bundle context.
+     * @return the default log level.
+     */
+    private static int getDefaultLevel(BundleContext context) {
+        // First check in the framework and in the system properties
+        String level = context.getProperty(IPOJO_LOG_LEVEL);
+        
+        // If null, look in bundle manifest
+        if (level == null) {
+            level = (String) context.getBundle().getHeaders().get(IPOJO_LOG_LEVEL);
+        }
+        
+        if (level != null) {
+            if (level.equalsIgnoreCase("info")) {
+                return INFO;
+            } else if (level.equalsIgnoreCase("debug")) {
+                return DEBUG;
+            } else if (level.equalsIgnoreCase("warning")) {
+                return WARNING;
+            } else if (level.equalsIgnoreCase("error")) {
+                return ERROR;
+            }
+        }
+        
+        // Either l is null, either the specified log level was unknown
+        // Set the default to WARNING
+        return WARNING;
+        
+    }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java
new file mode 100644
index 0000000..948b66b
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java
@@ -0,0 +1,472 @@
+/* 
+ * 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.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.FieldInterceptor;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.parser.ParseUtils;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Property class managing a property.
+ * This class allows storing property value and calling setter method too.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Property implements FieldInterceptor {
+
+    /**
+     * Name of the property (filed name if not set).
+     */
+    private String m_name;
+
+    /**
+     * Field of the property.
+     */
+    private String m_field;
+
+    /**
+     * Setter method of the property.
+     */
+    private Callback m_method;
+
+    /**
+     * Value of the property.
+     */
+    private Object m_value;
+
+    /**
+     * Type of the property.
+     */
+    private Class m_type;
+
+    /**
+     * Handler object on to use the logger.
+     */
+    private Handler m_handler;
+    
+    /**
+     * Instance Manager.
+     */
+    private InstanceManager m_manager;
+
+    /**
+     * Configurable Property Constructor. At least the method or the field need
+     * to be referenced.
+     * 
+     * @param name : name of the property (optional)
+     * @param field : name of the field
+     * @param method : method name
+     * @param value : initial value of the property (optional)
+     * @param type : the type of the property
+     * @param manager : instance manager
+     * @param handler : handler object which manage this property.
+     * @throws ConfigurationException : occurs when the property value cannot be set.
+     */
+    public Property(String name, String field, String method, String value, String type, InstanceManager manager, Handler handler) throws ConfigurationException {
+        m_handler = handler;
+        m_manager = manager;
+        m_field = field;
+
+        if (name == null) {
+            if (m_field == null) {
+                m_name = method;
+            } else {
+                m_name = field;
+            }
+        } else {
+            m_name = name;
+        }
+        
+        m_field = field;
+        m_type = computeType(type, manager.getGlobalContext());
+        if (value != null) {
+            m_value = create(m_type, value);
+        }
+
+        if (method != null) {
+            m_method = new Callback(method, new String[] { m_type.getName() }, false, manager);
+        }
+
+    }
+
+    /**
+     * The set type method computes and returns the property type according to the given type name.
+     * @param type : the type name
+     * @param context : bundle context (used to load classes)
+     * @return the class of the given type
+     * @throws ConfigurationException if an error occurs when loading the type class for non-primitive types.
+     */
+    public static Class computeType(String type, BundleContext context) throws ConfigurationException {
+        // Array :
+        if (type.endsWith("[]")) {
+            return computeArrayType(type, context);
+        } else {
+            // Syntactic sugar to avoid writing java.lang.String
+            if ("string".equals(type) || "String".equals(type)) {
+                return java.lang.String.class;
+            } else if ("boolean".equals(type)) {
+                return Boolean.TYPE;
+            } else if ("byte".equals(type)) {
+                return Byte.TYPE;
+            } else if ("short".equals(type)) {
+                return  Short.TYPE;
+            } else if ("int".equals(type)) {
+                return Integer.TYPE;
+            } else if ("long".equals(type)) {
+                return Long.TYPE;
+            } else if ("float".equals(type)) {
+                return Float.TYPE;
+            } else if ("double".equals(type)) {
+                return Double.TYPE;
+            } else if ("char".equals(type)) {
+                return Character.TYPE;
+            } else {
+                // Non array, complex type.
+                try {
+                    return context.getBundle().loadClass(type);
+                } catch (ClassNotFoundException e) {
+                    throw new ConfigurationException("Class not found exception in setValue on " + type + " : " + e.getMessage());
+                } catch (SecurityException e) {
+                    throw new ConfigurationException("Security excption in setValue on " + type + " : " + e.getMessage());
+                } catch (IllegalArgumentException e) {
+                    throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
+                }
+            }
+        }
+    }
+
+    /**
+     * Get the Class object of a type array.
+     * @param type : the string descriptor of the type (must end by [] )
+     * @param context : bundle context (used to load classes)
+     * @return the Class object of the given type array.
+     * @throws ConfigurationException : if the class cannot be loaded
+     */
+    private static Class computeArrayType(String type, BundleContext context) throws ConfigurationException {
+        String internalType = type.substring(0, type.length() - 2);
+        if ("string".equals(internalType) || "String".equals(internalType)) {
+            return new String[0].getClass();
+        }
+        if ("boolean".equals(internalType)) {
+            return new boolean[0].getClass();
+        }
+        if ("byte".equals(internalType)) {
+            return new byte[0].getClass();
+        }
+        if ("short".equals(internalType)) {
+            return new short[0].getClass();
+        }
+        if ("int".equals(internalType)) {
+            return new int[0].getClass();
+        }
+        if ("long".equals(internalType)) {
+            return new long[0].getClass();
+        }
+        if ("float".equals(internalType)) {
+            return new float[0].getClass();
+        }
+        if ("double".equals(internalType)) {
+            return new double[0].getClass();
+        }
+        if ("char".equals(internalType)) {
+            return new char[0].getClass();
+        }
+
+        // Complex array type.
+        try {
+            Class clazz = context.getBundle().loadClass(internalType);
+            Object[] object = (Object[]) Array.newInstance(clazz, 0);
+            return object.getClass();
+        } catch (ClassNotFoundException e) {
+            throw new ConfigurationException("Class not found exception in setValue on " + internalType);
+        } catch (SecurityException e) {
+            throw new ConfigurationException("Secutiry Exception in setValue on " + internalType);
+        } catch (IllegalArgumentException e) {
+            throw new ConfigurationException("Argument problem to call the constructor of the type " + internalType);
+        }
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+    public String getField() {
+        return m_field;
+    }
+
+    /**
+     * Get method name, null if no method.
+     * @return the method name.
+     */
+    public String getMethod() {
+        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() {
+        return m_value;
+    }
+
+    /**
+     * Fix the value of the property.
+     * @param value : the new value.
+     */
+    public void setValue(Object value) {
+        // Is the object is directly assignable to the property, affect it.
+        if (isAssignable(m_type, value)) {
+            m_value = value;
+        } else {
+            // If the object is a String, we must recreate the object from the String form
+            if (value instanceof String) {
+                try {
+                    m_value = create(m_type, (String) value);
+                } catch (ConfigurationException e) {
+                    throw new ClassCastException("Incompatible type for the property " + m_name + " : " + e.getMessage());
+                }
+            } else {
+                // Error, the given property cannot be injected.
+                throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type.getName() + " expected, " + value.getClass() + " received");
+            }
+        }
+    }
+
+    /**
+     * Test if the given value is assignable to the given type.
+     * @param type : class of the type
+     * @param value : object to check
+     * @return true if the object is assignable in the property of type 'type'.
+     */
+    public static boolean isAssignable(Class type, Object value) {
+        if (value == null || type.isInstance(value)) { // When the value is null, the assign works necessary.
+            return true;
+        } else if (type.isPrimitive()) {
+            // Manage all boxing types.
+            if (value instanceof Boolean && Boolean.TYPE.equals(type)) { return true; }
+            if (value instanceof Byte && Byte.TYPE.equals(type)) { return true; }
+            if (value instanceof Short && Short.TYPE.equals(type)) { return true; }
+            if (value instanceof Integer && Integer.TYPE.equals(type)) { return true; }
+            if (value instanceof Long && Long.TYPE.equals(type)) { return true; }
+            if (value instanceof Float && Float.TYPE.equals(type)) { return true; }
+            if (value instanceof Double && Double.TYPE.equals(type)) { return true; }
+            if (value instanceof Character && Character.TYPE.equals(type)) { return true; }
+            return false;
+        } else {
+            // Else return false.
+            return false;
+        }
+    }
+
+    /**
+     * Create an object of the given type with the given String value.
+     * @param type : type of the returned object
+     * @param strValue : String value.
+     * @return the object of type 'type' created from the String 'value'
+     * @throws ConfigurationException occurs when the object cannot be created.
+     */
+    public static Object create(Class type, String strValue) throws ConfigurationException {
+        if (Boolean.TYPE.equals(type)) { return new Boolean(strValue); }
+        if (Byte.TYPE.equals(type)) { return new Byte(strValue); }
+        if (Short.TYPE.equals(type)) { return new Short(strValue); }
+        if (Integer.TYPE.equals(type)) { return new Integer(strValue); }
+        if (Long.TYPE.equals(type)) { return new Long(strValue); }
+        if (Float.TYPE.equals(type)) { return new Float(strValue); }
+        if (Double.TYPE.equals(type)) { return new Double(strValue); }
+        if (Character.TYPE.equals(type)) { return new Character(strValue.charAt(0)); }
+
+        // Array :
+        if (type.isArray()) { return createArrayObject(type.getComponentType(), ParseUtils.parseArrays(strValue)); }
+        // Else it is a neither a primitive type neither a String -> create
+        // the object by calling a constructor with a string in argument.
+        try {
+            Constructor cst = type.getConstructor(new Class[] { String.class });
+            return cst.newInstance(new Object[] { strValue });
+        } catch (SecurityException e) {
+            throw new ConfigurationException("Security exception in create on " + type + " : " + e.getMessage());
+        } catch (NoSuchMethodException e) {
+            throw new ConfigurationException("Constructor not found exception in create on " + type + " : " + e.getMessage());
+        } catch (IllegalArgumentException e) {
+            throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
+        } catch (InstantiationException e) {
+            throw new ConfigurationException("Instantiation problem  " + type);
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Illegal Access " + type);
+        } catch (InvocationTargetException e) {
+            throw new ConfigurationException("Invocation problem " + type + " : " + e.getTargetException().getMessage());
+        }
+
+    }
+
+    /**
+     * Create an array object containing the type 'interntype' from the String array 'values'.
+     * @param interntype : internal type of the array.
+     * @param values : String array
+     * @return the array containing objects created from the 'values' array
+     * @throws ConfigurationException occurs when the array cannot be created correctly
+     */
+    public static Object createArrayObject(Class interntype, String[] values) throws ConfigurationException {
+        if (Boolean.TYPE.equals(interntype)) {
+            boolean[] bool = new boolean[values.length];
+            for (int i = 0; i < values.length; i++) {
+                bool[i] = new Boolean(values[i]).booleanValue();
+            }
+            return bool;
+        }
+        if (Byte.TYPE.equals(interntype)) {
+            byte[] byt = new byte[values.length];
+            for (int i = 0; i < values.length; i++) {
+                byt[i] = new Byte(values[i]).byteValue();
+            }
+            return byt;
+        }
+        if (Short.TYPE.equals(interntype)) {
+            short[] shor = new short[values.length];
+            for (int i = 0; i < values.length; i++) {
+                shor[i] = new Short(values[i]).shortValue();
+            }
+            return shor;
+        }
+        if (Integer.TYPE.equals(interntype)) {
+            int[] ints = new int[values.length];
+            for (int i = 0; i < values.length; i++) {
+                ints[i] = new Integer(values[i]).intValue();
+            }
+            return ints;
+        }
+        if (Long.TYPE.equals(interntype)) {
+            long[] longs = new long[values.length];
+            for (int i = 0; i < values.length; i++) {
+                longs[i] = new Long(values[i]).longValue();
+            }
+            return longs;
+        }
+        if (Float.TYPE.equals(interntype)) {
+            float[] floats = new float[values.length];
+            for (int i = 0; i < values.length; i++) {
+                floats[i] = new Float(values[i]).floatValue();
+            }
+            return floats;
+        }
+        if (Double.TYPE.equals(interntype)) {
+            double[] doubles = new double[values.length];
+            for (int i = 0; i < values.length; i++) {
+                doubles[i] = new Double(values[i]).doubleValue();
+            }
+            return doubles;
+        }
+        if (Character.TYPE.equals(interntype)) {
+            char[] chars = new char[values.length];
+            for (int i = 0; i < values.length; i++) {
+                chars[i] = values[i].toCharArray()[0];
+            }
+            return chars;
+        }
+
+        // Else it is a neither a primitive type -> create the
+        // object by calling a constructor with a string in argument.
+        try {
+            Constructor cst = interntype.getConstructor(new Class[] { String.class });
+            Object[] object = (Object[]) Array.newInstance(interntype, values.length);
+            for (int i = 0; i < values.length; i++) {
+                object[i] = cst.newInstance(new Object[] { values[i].trim() });
+            }
+            return object;
+        } catch (NoSuchMethodException e) {
+            throw new ConfigurationException("Constructor not found exception in setValue on " + interntype.getName());
+        } catch (IllegalArgumentException e) {
+            throw new ConfigurationException("Argument problem to call the constructor of the type " + interntype.getName());
+        } catch (InstantiationException e) {
+            throw new ConfigurationException("Instantiation problem  " + interntype.getName());
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Illegal Access Exception in  " + interntype.getName());
+        } catch (InvocationTargetException e) {
+            throw new ConfigurationException("Invocation problem " + interntype.getName() + " : " + e.getTargetException().getMessage());
+        }
+    }
+
+    /**
+     * Invoke the setter method on the given pjo object. If no specified pojo object, will call on each created pojo object.
+     * @param instance : the created object (could be null
+     * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)
+     */
+    public void invoke(Object instance) {
+        try {
+            if (instance == null) {
+                m_method.call(new Object[] { m_value });
+            } else {
+                m_method.call(instance, new Object[] { m_value });
+            }
+        } catch (NoSuchMethodException e) {
+            m_handler.error("The method " + m_method + " does not exist in the class " + m_manager.getClassName());
+            m_manager.stop();
+        } catch (IllegalAccessException e) {
+            m_handler.error("The method " + m_method + " is not accessible in the class " + m_manager.getClassName());
+            m_manager.stop();
+        } catch (InvocationTargetException e) {
+            m_handler.error("The method " + m_method + " in the class " + m_manager.getClassName() + "throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());
+            m_manager.setState(ComponentInstance.INVALID);
+        }
+    }
+
+    /**
+     * A field value is required by the object 'pojo'.
+     * @param pojo : POJO object
+     * @param fieldName : field
+     * @param value : last value
+     * @return the value if the handler want to inject this value.
+     * @see org.apache.felix.ipojo.FieldInterceptor#onGet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public Object onGet(Object pojo, String fieldName, Object value) {
+        return getValue();
+    }
+
+    /**
+     * The field 'field' receives a new value.
+     * @param pojo : pojo
+     * @param fieldName : field name
+     * @param value : new value
+     * @see org.apache.felix.ipojo.FieldInterceptor#onSet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public void onSet(Object pojo, String fieldName, Object value) {
+        setValue(value);
+        
+    }
+}
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
index 1c8ae1d..7dd3349 100644
--- 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
@@ -42,7 +42,7 @@
     /**
      * Bundle context against which this Tracker object is tracking.
      */
-    protected final BundleContext m_context;
+    protected BundleContext m_context;
 
     /**
      * Filter specifying search criteria for the services to track.
@@ -52,22 +52,22 @@
     /**
      * TrackerCustomizer object for this tracker.
      */
-    final TrackerCustomizer m_customizer;
+    protected 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;
+    protected 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;
+    private String m_trackClass;
 
     /**
      * Reference to be tracked. If this field is set, then we are tracking a single ServiceReference.
      */
-    private final ServiceReference m_trackReference;
+    private ServiceReference m_trackReference;
 
     /**
      * Tracked services: ServiceReference object -> customized. Object and ServiceListener object
@@ -126,13 +126,13 @@
         } else {
             m_customizer = customizer;
         }
-        this.m_listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        this.m_listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz + ")";
         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$
+            throw new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage());
         }
     }
 
@@ -157,7 +157,7 @@
             m_customizer = customizer;
         }
         if ((context == null) || (filter == null)) { // we throw a NPE here to be consistent with the other constructors
-            throw new NullPointerException();
+            throw new NullPointerException(); // NOPMD by clement on 29/02/08 14:12
         }
     }
 
@@ -188,7 +188,7 @@
                 // the initial
                 // references
             } catch (InvalidSyntaxException e) {
-                throw new RuntimeException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+                throw new IllegalStateException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
             }
         }
         /* Call tracked outside of synchronized region */
@@ -220,8 +220,8 @@
 
         try {
             m_context.removeServiceListener(outgoing);
-        } catch (IllegalStateException e) {
-            System.err.println("Context stopped");
+        } catch (IllegalStateException e) { //NOPMD
+            //System.err.println("Context stopped");
             /* In case the context was stopped. */
         }
         if (references != null) {
@@ -254,7 +254,7 @@
      * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
      */
     public void addedService(ServiceReference reference) {
-
+        // Nothing to do.
     }
 
     /**
@@ -266,6 +266,7 @@
      * @see TrackerCustomizer
      */
     public void modifiedService(ServiceReference reference, Object service) {
+        // Nothing to do.
     }
 
     /**
@@ -326,8 +327,7 @@
             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;
         }
     }
@@ -353,6 +353,31 @@
             return references;
         }
     }
+    
+    /**
+     * Return the list of references used by the tracker.
+     * A reference becomes used when the dependency has already
+     * call getService on this reference.
+     * @return : the list of used references.
+     */
+    public List/*<ServiceReference>*/getUsedServiceReferences() {
+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+        if (tracked == null || tracked.size() == 0) { // if Tracker is not open or empty
+            return null;
+        }
+        synchronized (tracked) {
+            int length = tracked.size();
+            List references = new ArrayList();
+            Iterator keys = tracked.keySet().iterator();
+            for (int i = 0; i < length; i++) {
+                Object key = keys.next(); 
+                if (tracked.get(key) != null) {
+                    references.add(key);
+                }
+            }
+            return references;
+        }
+    }
 
     /**
      * Returns a ServiceReference object for one of the services being tracked by this Tracker object.
@@ -388,11 +413,13 @@
         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);
+            if (object == null) {
+                if (tracked.containsKey(reference)) { // Not already get but already tracked.
+                    object = m_context.getService(reference);
+                    tracked.put(reference, object);
+                    return object;
+                }
+            } else { // The object was already get.
                 return object;
             }
             // Not already tracked.
@@ -430,10 +457,10 @@
         synchronized (tracked) {
             ServiceReference[] references = getServiceReferences();
             int length = 0;
-            if (references != null) {
-                length = references.length;
-            } else {
+            if (references == null) {
                 return null;
+            } else {
+                length = references.length;
             }
             Object[] objects = new Object[length];
             for (int i = 0; i < length; i++) {
@@ -541,7 +568,7 @@
             while (true) {
                 ServiceReference reference;
                 synchronized (this) {
-                    if (m_initial.size() == 0) { //  if there are no more inital services
+                    if (m_initial.isEmpty()) { //  if there are no more inital services
                         return; // we are done
                     }
 
@@ -580,14 +607,14 @@
             switch (event.getType()) {
                 case ServiceEvent.REGISTERED:
                 case ServiceEvent.MODIFIED:
-                    if (m_listenerFilter != null) { // constructor supplied filter
-                        track(reference);
-                    } else { // user supplied filter
+                    if (m_listenerFilter == null) { // user supplied filter 
                         if (m_filter.match(reference)) {
                             track(reference); // Arrival
                         } else {
                             untrack(reference); // Departure
                         }
+                    } else { // constructor supplied filter
+                        track(reference);
                     }
                     break;
                 case ServiceEvent.UNREGISTERING:
diff --git a/ipojo/core/src/main/resources/metadata.xml b/ipojo/core/src/main/resources/metadata.xml
index 9d02336..3163416 100644
--- a/ipojo/core/src/main/resources/metadata.xml
+++ b/ipojo/core/src/main/resources/metadata.xml
@@ -1,41 +1,27 @@
 <ipojo>
-<!-- Primitives handler -->
-<handler classname="org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler" name="controller" architecture="false"/>
-<handler classname="org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler" name="callback" level="1" architecture="false"/>
-<handler classname="org.apache.felix.ipojo.handlers.dependency.DependencyHandler" name="requires" level="0" architecture="false">
-	<controller field="m_state"/>
-</handler>
-<handler classname="org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler" name="provides" level="3" architecture="false"/>
-<handler classname="org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler" name="properties" level="1" architecture="false"/>
-<handler classname="org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler" name="architecture" architecture="false">
-	<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" architecture="false">
-	<controller field="m_isValid"/>
-	<requires filter="(&amp;(factory.state=1)(factory.name=*))" field="m_factories" optional="true" architecture="false">
-		<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" architecture="false">
-	<controller field="m_valid"/>
-</handler>
-<handler classname="org.apache.felix.ipojo.composite.service.importer.ExportHandler" name="exports" type="composite" architecture="false">
-	<controller field="m_valid"/>
-</handler>
-<handler classname="org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler" name="service" type="composite" architecture="false">
-	<controller field="m_isValid"/>
-</handler>
-<handler classname="org.apache.felix.ipojo.composite.service.provides.ProvidedServiceHandler" name="provides" type="composite" architecture="false">
-	<controller field="m_valid"/>
-</handler>
-<handler classname="org.apache.felix.ipojo.composite.architecture.ArchitectureHandler" name="architecture" type="composite" architecture="false">
-	<provides>
-		<property field="m_name" name="instance.name" value=""/>
-	</provides>
-</handler>
+	<!-- Primitives handler -->
+	<handler
+		classname="org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler"
+		name="controller" architecture="false" />
+	<handler
+		classname="org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler"
+		name="callback" level="1" architecture="false" />
+	<handler
+		classname="org.apache.felix.ipojo.handlers.dependency.DependencyHandler"
+		name="requires" level="0" architecture="false">
+		<!-- <controller field="m_state"/>  -->
+	</handler>
+	<handler
+		classname="org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler"
+		name="provides" level="3" architecture="false" />
+	<handler
+		classname="org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler"
+		name="properties" level="1" architecture="false" />
+	<handler
+		classname="org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler"
+		name="architecture" architecture="false">
+		<provides>
+			<property field="m_name" name="instance.name" value="" />
+		</provides>
+	</handler>
 </ipojo>
\ No newline at end of file
