Commit the new iPOJO version (0.7.6).

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@642265 13f79535-47bb-0310-9956-ffa450edef68
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