Applied patch (FELIX-266) to add support to iPOJO for composite 
services.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@527156 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java b/ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
index c9779a5..4a821f8 100644
--- a/ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
+++ b/ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
@@ -207,7 +207,7 @@
 		name = name.toLowerCase();
 		Element[] list = new Element[0];
 		for (int i = 0; i < m_elements.length; i++) {
-			if (m_elements[i].getName().equals(name) && m_elements[i].getNameSpace().equals("")) {
+			if (m_elements[i].getName().equalsIgnoreCase(name) && m_elements[i].getNameSpace().equals("")) {
 				list = Element.addElement(list, m_elements[i]);
 			}
 		}
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
index 30fb273..d988294 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
@@ -72,8 +72,9 @@
 	
 	/**
 	 * @return the method list.
+	 * Modified for performance issue.
 	 */
-	public List getMethods() { return m_methods; }
+	public List getMethods() { /*return m_methods;*/ return new ArrayList(); }
 
 	/**
      * Manipulate the class.
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/XMLMetadataParser.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/XMLMetadataParser.java
index 66ac076..030eee5 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/XMLMetadataParser.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/XMLMetadataParser.java
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.ipojo.parser;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.logging.Level;
 
 import org.apache.felix.ipojo.metadata.Attribute;
@@ -41,15 +43,38 @@
      * @throws ParseException when an error occurs in the xml parsing
      */
     public Element[] getComponentsMetadata() throws ParseException {
-    	return m_elements[0].getElements("Component");
+    	Element[] comp = m_elements[0].getElements("Component");
+    	Element[] compo = m_elements[0].getElements("Composite");
+    	Element[] metadata = new Element[comp.length + compo.length];
+    	int l = 0;
+    	for(int i = 0; i < comp.length; i++) { metadata[l] = comp[i]; l++;}
+    	for(int i = 0; i < compo.length; i++) { metadata[l] = compo[i]; l++;}
+    	return metadata;
+    }
+    
+    public List getReferredPackages() {
+    	List referred = new ArrayList();
+    	Element[] compo = m_elements[0].getElements("Composite");
+    	for(int i= 0; i < compo.length; i++) {
+    		for(int j = 0; j < compo[i].getElements().length; j++) {
+    			if(compo[i].getElements()[j].containsAttribute("specification")) {
+    				String p = compo[i].getElements()[j].getAttribute("specification");
+    				int last = p.lastIndexOf('.');
+    				if(last != -1) { referred.add(p.substring(0, last)); }
+    			}
+    		}
+    	}
+    	return referred;
     }
     
     public Element[] getMetadata() throws ParseException {
     	Element[] comp = m_elements[0].getElements("Component");
+    	Element[] compo = m_elements[0].getElements("Composite");
     	Element[] conf = m_elements[0].getElements("Instance");
-    	Element[] metadata = new Element[comp.length + conf.length];
+    	Element[] metadata = new Element[comp.length + conf.length + compo.length];
     	int l = 0;
     	for(int i = 0; i < comp.length; i++) { metadata[l] = comp[i]; l++;}
+    	for(int i = 0; i < compo.length; i++) { metadata[l] = compo[i]; l++;}
     	for(int i = 0; i < conf.length; i++) { metadata[l] = conf[i]; l++;}
     	return metadata;
     }
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
index 29b9659..c61f91a 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
@@ -151,7 +151,8 @@
 	 */
 	private OsgiManifest				osgiManifest;
 	
-	private String[][] namespaces; 
+	private String[][] namespaces;
+	private List referedPackages; 
 
 	/**
 	 * Execute this Mojo
@@ -482,6 +483,12 @@
 			}
 		}
 		
+		// Add refered imports form the metadata
+		for(int i = 0; i < referedPackages.size(); i++) {
+			String pack = (String) referedPackages.get(i);
+			referred.add(pack);
+		}
+		
 		// Add org.apache.felix.ipojo, org.apache.felix.ipojo.architecture is not already in the set
 		referred.add(IPojoPluginConfiguration.ipojo_package);
 		referred.add(IPojoPluginConfiguration.ipojo_arch_package);
@@ -872,6 +879,7 @@
 			parser.parse(is);
 		    
 		    meta = handler.getMetadata();
+		    referedPackages = handler.getReferredPackages();
 		    
 		} catch (MalformedURLException e) {
 			getLog().error("Malformed URL for " + outputDirectory+path+ "("+e.getMessage()+")");
diff --git a/ipojo/pom.xml b/ipojo/pom.xml
index 08adf4d..eb1ea8d 100644
--- a/ipojo/pom.xml
+++ b/ipojo/pom.xml
@@ -52,6 +52,7 @@
               org.apache.felix.ipojo.util,
               org.apache.felix.ipojo.handlers.dependency,
               org.apache.felix.ipojo.handlers.providedservice, 
+              org.apache.felix.ipojo.composite,
               org.osgi.service.cm; specification-version="1.2",
               org.osgi.service.log; specification-version="1.3"
             </exportPackage>
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index b873c2f..2d66c3d 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -51,6 +51,11 @@
      * The key of this hashmap is the name (i.e. pid) of the created instance
      */
     private HashMap m_componentInstances = new HashMap();
+    
+    /**
+     * Ture if the component is a composition. 
+     */
+    private boolean m_isComposite = false;
 
     /**
      * The bundle context reference.
@@ -66,6 +71,11 @@
      * Component Implementation Class Name.
      */
     private String m_componentClassName = null;
+    
+    /**
+     * Composition Name. 
+     */
+    private String m_compositeName = null;
 
     /**
      * Classloader to delegate loading.
@@ -97,6 +107,11 @@
      * Logger for the factory (and all component instance).
      */
     private Logger m_logger;
+    
+    /**
+     * True when the factory is active (non stopping and non starting).
+     */
+    private boolean m_active = false;
 
     /**
      * FactoryClassloader.
@@ -183,19 +198,44 @@
      */
     public ComponentFactory(BundleContext bc, Element cm) {
         m_context = bc;
-        m_componentClassName = cm.getAttribute("className");
         m_componentMetadata = cm;
-        
-        // Get factory PID :
-        if (m_componentMetadata.containsAttribute("factory") && !m_componentMetadata.getAttribute("factory").equalsIgnoreCase("no")) { 
-        	m_factoryName = m_componentMetadata.getAttribute("factory");
-        } else { m_factoryName = m_componentMetadata.getAttribute("className"); }
-        
-        m_logger = new Logger(m_context, m_factoryName, Logger.WARNING);
+        if (cm.getName().equalsIgnoreCase("composite")) {
+        	m_componentClassName = null;
+        	m_isComposite = true;
+        	// Get the name
+        	if (cm.containsAttribute("name")) { 
+        		m_compositeName = cm.getAttribute("name");
+        	} else { 
+        		System.err.println("A composite needs a name"); return;
+        	}
+        	// Compute factory name
+        	if (m_componentMetadata.containsAttribute("factory") && !m_componentMetadata.getAttribute("factory").equalsIgnoreCase("no")) { 
+            	m_factoryName = m_componentMetadata.getAttribute("factory");
+            } else { m_factoryName = m_compositeName; }
+        } else  {
+        	if (cm.containsAttribute("className")) { 
+        		m_componentClassName = cm.getAttribute("className");
+        	} else { 
+        		System.err.println("A component needs a class name"); return;
+        	}
+        	if (m_componentMetadata.containsAttribute("factory") && !m_componentMetadata.getAttribute("factory").equalsIgnoreCase("no")) { 
+            	m_factoryName = m_componentMetadata.getAttribute("factory");
+            } else { m_factoryName = m_componentMetadata.getAttribute("className"); }
+        }
+        if (m_factoryName != null) {
+        	m_logger = new Logger(m_context, m_factoryName, Logger.WARNING);
+        } else {
+        	if (m_isComposite) {
+        		m_logger = new Logger(m_context, m_compositeName, Logger.WARNING);
+        	} else {
+        		m_logger = new Logger(m_context, m_componentClassName, Logger.WARNING);
+        	}
+        }
     }
 
     /**
      * Create a instance manager factory. The class is given in parameter.
+     * The component type is not a composite.
      * @param bc : bundle context
      * @param clazz : the component class
      * @param cm : metadata of the component
@@ -217,12 +257,15 @@
     /**
      * Stop all the instance managers.
      */
-    public void stop() {
+    public synchronized void stop() {
+    	m_active = false;
         Collection col = m_componentInstances.values();
         Iterator it = col.iterator();
         while (it.hasNext()) {
             ComponentInstance ci = (ComponentInstance) it.next();
-            if (ci.isStarted()) { ci.stop(); }
+            if (ci.isStarted()) {
+            	ci.stop();
+            }
         }
         m_componentInstances.clear();
         if (m_sr != null) { m_sr.unregister(); }
@@ -232,20 +275,33 @@
     /**
      * Start all the instance managers.
      */
-    public void start() {        
+    public synchronized void start() {        
         Properties props = new Properties();
 
         // create a ghost component
-        InstanceManager ghost = new InstanceManager(this, m_context);
-        Properties p = new Properties();
-        p.put("name", "ghost");
-        ghost.configure(m_componentMetadata, p);
-        m_componentDesc = ghost.getComponentDescription();
+        if (!m_isComposite) {
+        	InstanceManager ghost = new InstanceManager(this, m_context);
+        	Properties p = new Properties();
+        	p.put("name", "ghost");
+        	ghost.configure(m_componentMetadata, p);
+        	m_componentDesc = ghost.getComponentDescription();
+        } else {
+        	CompositeManager ghost = new CompositeManager(this, m_context);
+        	Properties p = new Properties();
+        	p.put("name", "ghost");
+        	ghost.configure(m_componentMetadata, p);
+        	m_componentDesc = ghost.getComponentDescription();
+        }
         
         // Check if the factory should be exposed
         if (m_componentMetadata.containsAttribute("factory") && m_componentMetadata.getAttribute("factory").equalsIgnoreCase("no")) { return; }
         
-        props.put("component.class", m_componentClassName);
+        if (!m_isComposite) { 
+        	props.put("component.class", m_componentClassName);
+        } else { 
+        	props.put("component.class", "no implementation class"); 
+        }
+        props.put("factory.name", m_factoryName);
         props.put("component.providedServiceSpecifications", m_componentDesc.getprovidedServiceSpecification());
         props.put("component.properties", m_componentDesc.getProperties());
         props.put("component.description", m_componentDesc);
@@ -255,8 +311,19 @@
         props.put(Constants.SERVICE_PID, m_factoryName);
 
         // Exposition of the factory service
+        m_active = true;
         m_sr = m_context.registerService(new String[] {Factory.class.getName(), ManagedServiceFactory.class.getName()}, this, props);
     }
+    
+    /**
+     * Callback called by instance when stopped.
+     * @param ci : the instance stopping
+     */
+    protected synchronized void stopped(ComponentInstance ci) {
+    	if (m_active) {
+    		m_componentInstances.remove(ci.getInstanceName());
+    	}
+    }
 
     /**
      * @see org.apache.felix.ipojo.Factory#getComponentInfo()
@@ -318,15 +385,30 @@
     	}
     	
         IPojoContext context = new IPojoContext(m_context);
-        InstanceManager instance = new InstanceManager(this, context);
-        context.setComponentInstance(instance);
-        instance.configure(m_componentMetadata, configuration);
+        ComponentInstance instance = null;
+        if (!m_isComposite) {
+        	InstanceManager inst = new InstanceManager(this, context);
+        	//context.setComponentInstance(inst);
+        	inst.configure(m_componentMetadata, configuration);
+        	instance = inst;
+        } else {
+        	CompositeManager inst = new CompositeManager(this, context);
+        	//context.setComponentInstance(inst);
+        	inst.configure(m_componentMetadata, configuration);
+        	instance = inst;
+        }
 
         String pid = null;
         if (configuration.get("name") != null) { 
         	pid = (String) configuration.get("name"); 
-        } else { pid = m_componentMetadata.getAttribute("className"); }
-
+        } else {
+        	throw new UnacceptableConfiguration("The name attribute is missing");
+        }
+        
+        if (m_componentInstances.containsKey(pid)) {
+        	throw new UnacceptableConfiguration("Name already used : " + pid);
+        }
+        
         m_componentInstances.put(pid, instance);
         instance.start();
         return instance;
@@ -342,17 +424,30 @@
     		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());
     	}
-    	
-    	IPojoContext context = new IPojoContext(m_context, serviceContext);
-        InstanceManager instance = new InstanceManager(this, context);
-        context.setComponentInstance(instance);
-        instance.configure(m_componentMetadata, configuration);
 
-        String pid = null;
+    	IPojoContext context = new IPojoContext(m_context, serviceContext);
+    	ComponentInstance instance = null;
+    	if (!m_isComposite) {
+        	InstanceManager inst = new InstanceManager(this, context);
+        	//context.setComponentInstance(inst);
+        	inst.configure(m_componentMetadata, configuration);
+        	instance = inst;
+        } else {
+        	CompositeManager inst = new CompositeManager(this, context);
+        	//context.setComponentInstance(inst);
+        	inst.configure(m_componentMetadata, configuration);
+        	instance = inst;
+        }
+
+    	String pid = null;
         if (configuration.get("name") != null) { 
         	pid = (String) configuration.get("name"); 
-        } else { 
-        	pid = m_componentMetadata.getAttribute("className");
+        } else {
+        	throw new UnacceptableConfiguration("The name attribute is missing");
+        }
+        
+        if (m_componentInstances.containsKey(pid)) {
+        	throw new UnacceptableConfiguration("Name already used : " + pid);
         }
 
         m_componentInstances.put(pid, instance);
@@ -450,7 +545,12 @@
 	public void reconfigure(Dictionary properties) throws UnacceptableConfiguration {
 		if (properties == null || properties.get("name") == null) { throw new UnacceptableConfiguration("The configuration does not contains the \"name\" property"); }
 		String name = (String) properties.get("name");
-		InstanceManager cm = (InstanceManager) m_componentInstances.get(name);
+		ComponentInstance cm = null;
+		if (m_isComposite) {
+			cm = (CompositeManager) m_componentInstances.get(name);
+		} else  {
+			cm = (InstanceManager) m_componentInstances.get(name);
+		}
         if (cm == null) { 
         	return;  // The instance does not exist.
         } else {
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
index 3fd4acd..9578dda 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
@@ -80,7 +80,7 @@
     ComponentFactory getFactory();
     
     /**
-     * @return the context of the instance manager
+     * @return the context of the component instance
      */
     BundleContext getContext();
     
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/CompositeHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
new file mode 100644
index 0000000..8dab9a6
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
@@ -0,0 +1,74 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Composite Handler Abstract Class.
+ * An composite handler need implements these method to be notifed of lifecycle change...
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public abstract class CompositeHandler {
+	
+	/**
+     * Configure the handler.
+     * @param im : the instance manager
+     * @param metadata : the metadata of the component
+     * @param configuration : the instance configuration
+     */
+    public abstract void configure(CompositeManager im, Element metadata, Dictionary configuration);
+
+    /**
+     * Stop the handler : stop the management.
+     */
+    public abstract void stop();
+
+    /**
+     * Start the handler : start the management.
+     */
+    public abstract void start();
+
+    /**
+     * Is the actual state valid for this handler ?
+     * @return true is the state seems valid for the handler
+     */
+    public boolean isValid() { return true; }
+
+    /**
+     * This method is called when the component state changed.
+     * @param state : the new state
+     */
+    public void stateChanged(int state) { }
+
+    /**
+     * @return the description of the handler..
+     */
+    public HandlerDescription getDescription() { return new HandlerDescription(this.getClass().getName(), isValid()); }
+
+	/**
+	 * The instance is reconfiguring.
+	 * @param configuration : New instance configuration.
+	 */
+	public void reconfigure(Dictionary configuration) { }
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/CompositeManager.java b/ipojo/src/main/java/org/apache/felix/ipojo/CompositeManager.java
new file mode 100644
index 0000000..d17f45d
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/CompositeManager.java
@@ -0,0 +1,364 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.composite.CompositeServiceContext;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * 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:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class CompositeManager implements ComponentInstance {
+	
+	/**
+     * Parent factory (ComponentFactory).
+     */
+    private ComponentFactory m_factory;
+    
+    /**
+     * Name of the component instance.
+     */
+    private String m_name;
+
+    /**
+     * The context of the component.
+     */
+    private BundleContext m_context;
+
+    /**
+     * Composite Handler list.
+     */
+    private CompositeHandler[] m_handlers = new CompositeHandler[0];
+
+    /**
+     * Component state (STOPPED at the beginning).
+     */
+    private int m_state = STOPPED;
+
+    /**
+     * Component type information.
+     */
+    private ComponentDescription m_componentDesc;
+    
+    /**
+     * Internal service context of the composition.
+     */
+    private CompositeServiceContext m_internalContext;
+    
+
+    // Constructor
+    /**
+     * Construct a new Component Manager.
+     * @param factory : the factory managing the instance manager
+     * @param bc : the bundle context to give to the instance
+     */
+    public CompositeManager(ComponentFactory factory, BundleContext bc) {
+        m_factory = factory;
+        m_context = bc;
+        // Initialize the service context.
+        m_internalContext = new CompositeServiceContext(m_context, this);
+        m_factory.getLogger().log(Logger.INFO, "[Bundle " + m_context.getBundle().getBundleId() + "] Create an instance manager from the factory " + m_factory);
+    }
+
+    /**
+     * Configure the instance manager.
+     * Stop the existings handler, clear the handler list, change the metadata, recreate the handlers
+     * @param cm : the component type metadata
+     * @param configuration : the configuration of the instance
+     */
+    public void configure(Element cm, Dictionary configuration) {
+        // Stop all previous registred handler
+        if (m_handlers.length != 0) { stop(); }
+
+        // Clear the handler list
+        m_handlers = new CompositeHandler[0];
+
+        // ComponentInfo initialization
+        m_componentDesc = new ComponentDescription(m_factory.getName());
+        
+        // Add the name
+        m_name = (String) configuration.get("name");
+
+        // Create the standard handlers and add these handlers to the list
+        for (int i = 0; i < IPojoConfiguration.INTERNAL_COMPOSITE_HANDLERS.length; i++) {
+            // Create a new instance
+            try {
+            	CompositeHandler h = (CompositeHandler) IPojoConfiguration.INTERNAL_COMPOSITE_HANDLERS[i].newInstance();
+                h.configure(this, cm, configuration);
+            } catch (InstantiationException e) {
+                m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
+            } catch (IllegalAccessException e) {
+                m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
+            }
+        }
+
+        // Look for namespaces
+        for (int i = 0; i < cm.getNamespaces().length; i++) {
+            if (!cm.getNamespaces()[i].equals("")) {
+                // It is not an internal handler, try to load it
+                try {
+                    Class c = m_context.getBundle().loadClass(cm.getNamespaces()[i]);
+                    CompositeHandler h = (CompositeHandler) c.newInstance();
+                    h.configure(this, cm, configuration);
+                } catch (ClassNotFoundException e) {
+                    m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
+                } catch (InstantiationException e) {
+                    m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
+                } catch (IllegalAccessException e) {
+                    m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    /**
+     * @return the component type information.
+     */
+    public ComponentDescription getComponentDescription() { return m_componentDesc; }
+    
+    /**
+     * @return the instance description.
+     */
+    public synchronized InstanceDescription getInstanceDescription() {
+    	int componentState = getState();
+        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_componentDesc);
+        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;
+    }
+
+    /**
+     * @return the list of the registred handlers.
+     */
+    public CompositeHandler[] getRegistredCompositeHandlers() { return m_handlers; }
+
+    /**
+     * Return a specified handler.
+     * @param name : class name of the handler to find
+     * @return : the handler, or null if not found
+     */
+    public CompositeHandler getCompositeHandler(String name) {
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i].getClass().getName().equalsIgnoreCase(name)) { return m_handlers[i]; }
+        }
+        return null;
+    }
+
+    // ===================== Lifecycle management =====================
+
+    /**
+     * Start the instance manager.
+     */
+    public void start() {
+    	if (m_state != STOPPED) { return; } // Instance already started
+    	
+        // Start all the handlers
+        m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] Start the instance manager with " + m_handlers.length + " handlers");
+
+        // The new state of the component is UNRESOLVED
+        m_state = INVALID;
+        
+        m_internalContext.start(); // Turn on the factory tracking
+
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].start();
+        }
+
+        // Defines the state of the component :
+        checkInstanceState();
+    }
+
+    /**
+     * Stop the instance manager.
+     */
+    public void stop() {
+    	if (m_state == STOPPED) { return; } // Instance already stopped
+    	
+        setState(INVALID);
+        // Stop all the handlers
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].stop();
+        }
+        
+        m_internalContext.stop(); // Turn off the factory tracking
+        m_state = STOPPED;
+        m_factory.stopped(this);
+    }
+
+    /**
+     * Set the state of the component.
+     * if the state changed call the stateChanged(int) method on the handlers
+     */
+    public void setState(int state) {
+        if (m_state != state) {
+
+            // Log the state change
+            if (state == INVALID) { m_factory.getLogger().log(Logger.INFO, "[" + m_name + "]  State -> INVALID"); }
+            if (state == VALID) { m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] State -> VALID"); }
+
+            // The state changed call the handler stateChange method
+            m_state = state;
+            for (int i = m_handlers.length - 1; i > -1; i--) {
+                m_handlers[i].stateChanged(state);
+            }
+        }
+    }
+
+    /**
+     * @return the actual state of the component.
+     */
+    public int getState() { return m_state; }
+    
+    /**
+     * @see org.apache.felix.ipojo.ComponentInstance#isStarted()
+     */
+    public boolean isStarted() { return m_state != STOPPED; }
+
+    // ===================== end Lifecycle management =====================
+
+    // ================== Class & Instance management ===================
+
+    /**
+     * @return the factory of the component
+     */
+    public ComponentFactory getFactory() { return m_factory; }
+
+    //  ======================== Handlers Management ======================
+
+    /**
+     * Register the given handler to the current instance manager.
+     * @param h : the handler to register
+     */
+    public void register(CompositeHandler h) {
+        for (int i = 0; (m_handlers != null) && (i < m_handlers.length); i++) {
+            if (m_handlers[i] == h) {
+                return;
+            }
+        }
+
+        if (m_handlers != null) {
+        	CompositeHandler[] newList = new CompositeHandler[m_handlers.length + 1];
+            System.arraycopy(m_handlers, 0, newList, 0, m_handlers.length);
+            newList[m_handlers.length] = h;
+            m_handlers = newList;
+        }
+    }
+
+    /**
+     * Unregister the given handler.
+     * @param h : the handler to unregiter
+     */
+    public void unregister(CompositeHandler h) {
+        int idx = -1;
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i] == h) {
+                idx = i;
+                break;
+            }
+        }
+
+        if (idx >= 0) {
+            if ((m_handlers.length - 1) == 0) {
+                m_handlers = new CompositeHandler[0];
+            } else {
+            	CompositeHandler[] newList = new CompositeHandler[m_handlers.length - 1];
+                System.arraycopy(m_handlers, 0, newList, 0, idx);
+                if (idx < newList.length)             {
+                    System.arraycopy(
+                            m_handlers, idx + 1, newList, idx, newList.length - idx);
+                }
+                m_handlers = newList;
+            }
+        }
+    }
+
+
+    /**
+     * @return the parent context of the instance.
+     */
+    public BundleContext getContext() { return m_context; }
+
+    /**
+     * Check the state of all handlers.
+     */
+    public void checkInstanceState() {
+        m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] Check the instance state");
+        boolean isValid = true;
+        for (int i = 0; i < m_handlers.length; i++) {
+            boolean b = m_handlers[i].isValid();
+            isValid = isValid && b;
+        }
+
+        // Update the component state if necessary
+        if (!isValid && m_state == VALID) {
+            // Need to update the state to UNRESOLVED
+            setState(INVALID);
+            return;
+        }
+        if (isValid && m_state == INVALID) { setState(VALID); }
+    }
+
+	/**
+	 * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
+	 */
+	public String getInstanceName() { return m_name; }
+
+	/**
+	 * @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);
+	    }
+	}
+	
+	/**
+	 * @return the internal service context.
+	 */
+	public ServiceContext getServiceContext() { return m_internalContext; }
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java b/ipojo/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
index 2df12ee..e431196 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.ipojo;
 
+import org.apache.felix.ipojo.composite.service.importer.ImportExportHandler;
+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;
@@ -49,4 +51,13 @@
         ArchitectureHandler.class
     };
 
+	/**
+	 * Available composite handlers in the iPOJO bundle.
+	 */
+	public static final Class[] INTERNAL_COMPOSITE_HANDLERS = new Class[] {
+		ServiceInstantiatorHandler.class,
+		ImportExportHandler.class,
+		org.apache.felix.ipojo.composite.architecture.ArchitectureHandler.class
+	};
+
 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/IPojoContext.java b/ipojo/src/main/java/org/apache/felix/ipojo/IPojoContext.java
index a654eeb..85166b7 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/IPojoContext.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/IPojoContext.java
@@ -196,12 +196,12 @@
 	 * Set the instance to the service context.
 	 * @param ci : the component instance
 	 */
-	public void setComponentInstance(ComponentInstance ci) { m_serviceContext.setComponentInstance(ci); }
+	//public void setComponentInstance(ComponentInstance ci) { m_serviceContext.setComponentInstance(ci); }
 	
 	/**
 	 * Get the instance manager from the service context.
 	 * @return the component manager of the service context
 	 */
-	public ComponentInstance getComponentInstance() { return m_serviceContext.getComponentInstance(); }
+	//public ComponentInstance getComponentInstance() { return m_serviceContext.getComponentInstance(); }
 
 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
index 29e885f..5f9cda3 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -165,7 +165,7 @@
      */
     public InstanceDescription getInstanceDescription() {
     	int componentState = getState();
-        InstanceDescription instanceDescription = new InstanceDescription(m_name, m_className, componentState, getContext().getBundle().getBundleId());
+        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_componentDesc);
 
         String[] objects = new String[getPojoObjects().length];
         for (int i = 0; i < getPojoObjects().length; i++) {
@@ -243,6 +243,8 @@
         m_pojoObjects = new Object[0];
         
         m_state = STOPPED;
+        
+        m_factory.stopped(this);
     }
 
     /**
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/ServiceContext.java b/ipojo/src/main/java/org/apache/felix/ipojo/ServiceContext.java
index 6afbe1b..24a4176 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/ServiceContext.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/ServiceContext.java
@@ -108,6 +108,6 @@
 	 * Set the component instance using the service context.
 	 * @param ci
 	 */
-	void setComponentInstance(ComponentInstance ci);
+	//void setComponentInstance(ComponentInstance ci);
 
 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
index 8598404..a55db2c 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
@@ -55,11 +55,23 @@
     }
     
     /**
+     * Constructor for composite.
+     * @param name : name of the component type (factory name). 
+     */
+    public ComponentDescription(String name) {
+    	m_name = name;
+    }
+    
+    /**
      * @see java.lang.Object#toString()
      */
     public String toString() {
         String res = "";
-        res += "Component Type : " + m_name + " (" + m_className + ") \n";
+        if (m_className == null) {
+        	res += "Component Type : " + m_name + " (Composition) \n";
+        } else {
+        	res += "Component Type : " + m_name + " (" + m_className + ") \n";
+        }
         for (int i = 0; i < m_providedServiceSpecification.length; i++) {
             res += "\tProvides : " + m_providedServiceSpecification[i] + "\n";
         }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
index ba0f895..39b7b6b 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
@@ -25,12 +25,6 @@
 public class InstanceDescription {
 
     /**
-     * The Component class name.
-     * This String is the identifier of the component.
-     */
-    private String m_className;
-
-    /**
      * The name of the component (instance).
      */
     private String m_name;
@@ -51,24 +45,35 @@
     private int m_state;
 
     /**
-     * BundleId of the component.
+     * BundleId who create the instance.
      */
     private long m_bundleId;
+    
+    /**
+     * Component Type of the instance.
+     */
+    private ComponentDescription m_type;
+    
+    /**
+     * COntained instance list.
+     */
+    private InstanceDescription[] m_containedInstances = new InstanceDescription[0];
 
     /**
      * Constructor.
      * @param name : the name of the component instance.
      * @param state : the state of the instance.
-     * @param className : implementation class name.
      * @param bundleId : bundle id owning this instance.
+     * @param cd : the component type description of this instance.
      */
-    public InstanceDescription(String name, String className, int state, long bundleId) {
+    public InstanceDescription(String name, int state, long bundleId, ComponentDescription cd) {
         m_name = name;
-        m_className = className;
         m_state = state;
         m_createdObjects = new String[0];
         m_handlers = new HandlerDescription[0];
+        m_containedInstances = new InstanceDescription[0];
         m_bundleId = bundleId;
+        m_type = cd;
     }
 
     /**
@@ -87,9 +92,9 @@
     public void setCreatedObjects(String[] objects) { m_createdObjects = objects; }
 
     /**
-     * @return : the class name of the component
+     * @return : the component type description of this instance.
      */
-    public String getClassName() { return m_className; }
+    public ComponentDescription getComponentDescription() { return m_type; }
 
     /**
      * @return the live handler list
@@ -113,6 +118,24 @@
         newHd[m_handlers.length] = hd;
         m_handlers = newHd;
     }
+    
+    /**
+     * Add an instance description to the contained instance list.
+     * @param inst : the handler description to add
+     */
+    public void addInstance(InstanceDescription inst) {
+        // Verify that the dependency description is not already in the array.
+        for (int i = 0; (i < m_containedInstances.length); i++) {
+            if (m_containedInstances[i] == inst) {
+                return; //NOTHING TO DO, the description is already in the array
+            }
+        }
+        // The component Description is not in the array, add it
+        InstanceDescription[] newCi = new InstanceDescription[m_containedInstances.length + 1];
+        System.arraycopy(m_containedInstances, 0, newCi, 0, m_containedInstances.length);
+        newCi[m_containedInstances.length] = inst;
+        m_containedInstances = newCi;
+    }
 
     /**
      * Set the state of the component.
@@ -129,6 +152,11 @@
      * @return the bundle id owning the component implementation class.
      */
     public long getBundleId() { return m_bundleId; }
+    
+    /**
+     * @return the list of contained instances.
+     */
+    public InstanceDescription[] getContainedInstances() { return m_containedInstances; }
 
 
 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
new file mode 100644
index 0000000..5f4bb40
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
@@ -0,0 +1,267 @@
+/* 
+ * 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 java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.ServiceContext;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+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;
+
+/**
+ * CompositeServiceContext Class.
+ * This class provides an implementation of the service context for composite.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class CompositeServiceContext implements ServiceContext, ServiceListener {
+	
+	private class Record {
+		private ServiceReference m_ref;
+		private ServiceRegistration m_reg;
+		private FactoryProxy m_fact;
+	}
+	
+	private List m_factories = new ArrayList();
+	
+	private BundleContext m_parent;
+	
+	/**
+	 * Internal service registry.
+	 */
+	private ServiceRegistry m_registry;
+	
+	/**
+	 * Component Instance who creates this registry. 
+	 */
+	private ComponentInstance m_instance;
+	
+	/**
+	 * 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;
+	}
+	
+	/**
+	 * Constructor.
+	 * @param bc : the bundle context
+	 * @param ci : the component instance owning this context
+	 */
+	public CompositeServiceContext(BundleContext bc, ComponentInstance ci) {
+		this(bc);
+		m_parent = bc;
+		m_instance = ci;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)
+	 */
+	public void addServiceListener(ServiceListener arg0) {
+		m_registry.addServiceListener(arg0);
+	}
+
+	/**
+	 * @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);
+	}
+
+	/**
+	 * @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);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.ServiceContext#getComponentInstance()
+	 */
+	public ComponentInstance getComponentInstance() {
+		return m_instance;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
+	 */
+	public Object getService(ServiceReference arg0) {
+		return m_registry.getService(m_instance, arg0);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
+	 */
+	public ServiceReference getServiceReference(String arg0) {
+		return m_registry.getServiceReference(arg0);
+	}
+
+	/**
+	 * @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);
+	}
+
+	/**
+	 * @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);
+	}
+
+	/**
+	 * @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);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
+	 */
+	public void removeServiceListener(ServiceListener arg0) {
+		m_registry.removeServiceListener(arg0);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
+	 */
+	public boolean ungetService(ServiceReference arg0) {
+		return m_registry.ungetService(m_instance, arg0);
+	}
+	
+	/**
+	 * Initiate the factory list.
+	 */
+	private void importFactories() {
+		try {
+			ServiceReference[] refs = m_parent.getServiceReferences(Factory.class.getName(), null);
+			if (refs != null) {
+				for (int i = 0; i < refs.length; i++) {
+					importFactory(refs[i]);
+				}
+			}
+		} catch (InvalidSyntaxException e) {
+			e.printStackTrace(); // Should not happen
+		}
+	}
+	
+	/**
+	 * Import a factory form the parent to the internal registry.
+	 * @param ref : the reference of the factory to import.
+	 */
+	private void importFactory(ServiceReference ref) {
+		//System.out.println("Add a new factory in the scope : " + ref.getProperty(Constants.SERVICE_PID));
+		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_parent.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) {
+		//System.out.println("Remove a factory from the scope : " + ref.getProperty(Constants.SERVICE_PID));
+		for (int i = 0; i < m_factories.size(); i++) {
+			Record rec = (Record) m_factories.get(i);
+			if (rec.m_ref == ref) {
+				rec.m_reg.unregister();
+				rec.m_fact = null;
+				m_parent.ungetService(rec.m_ref);
+				m_factories.remove(rec);
+				return;
+			}
+		}
+	}
+	
+	/**
+	 * Start the registry management.
+	 */
+	public void start() {
+		importFactories();
+		try {
+			m_parent.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")");
+		} catch (InvalidSyntaxException e) {
+			// Should not happen
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Stop the registry management.
+	 */
+	public synchronized void stop() {
+		m_parent.removeServiceListener(this);
+		m_registry.reset();
+		for (int i = 0; i < m_factories.size(); i++) {
+			Record rec = (Record) m_factories.get(i);
+			removeFactory(rec.m_ref);
+		}
+	}
+	
+	/**
+	 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+	 */
+	public void serviceChanged(ServiceEvent event) {
+		if (event.getType() == ServiceEvent.REGISTERED) {
+			if (!containsRef(event.getServiceReference())) {
+				importFactory(event.getServiceReference());
+			}
+			return;
+		}
+		if (event.getType() == ServiceEvent.UNREGISTERING) {
+			if (containsRef(event.getServiceReference())) {
+				removeFactory(event.getServiceReference());
+			}
+		}
+	}
+	
+	/**
+	 * 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;
+	}
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
new file mode 100644
index 0000000..0244ae9
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
@@ -0,0 +1,82 @@
+/* 
+ * 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 org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.architecture.ComponentDescription;
+
+/**
+ * Bridge representing a Factory inside a composition.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class FactoryProxy implements Factory {
+	
+	private Factory m_delegate;
+	private ServiceContext m_context;
+	
+	/**
+	 * Constructor.
+	 * @param fact : the targetted factory.
+	 * @param s : the service context to target.
+	 */
+	public FactoryProxy(Factory fact, ServiceContext s) {
+		m_delegate = fact;
+		m_context = s;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+	 */
+	public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration {
+		return m_delegate.createComponentInstance(configuration, m_context);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary, org.apache.felix.ipojo.ServiceContext)
+	 */
+	public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration {
+		return m_delegate.createComponentInstance(configuration, serviceContext);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Factory#getComponentDescription()
+	 */
+	public ComponentDescription getComponentDescription() { return m_delegate.getComponentDescription(); }
+
+	/**
+	 * @see org.apache.felix.ipojo.Factory#getName()
+	 */
+	public String getName() { return m_delegate.getName(); }
+
+	/**
+	 * @see org.apache.felix.ipojo.Factory#isAcceptable(java.util.Dictionary)
+	 */
+	public boolean isAcceptable(Dictionary conf) { return m_delegate.isAcceptable(conf); }
+
+	/**
+	 * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
+	 */
+	public void reconfigure(Dictionary conf) throws UnacceptableConfiguration { m_delegate.reconfigure(conf); }
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
new file mode 100644
index 0000000..ae2f1aa
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
@@ -0,0 +1,87 @@
+/* 
+ * 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 implemenation.
+ * This class is used for in the composition.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceReferenceImpl implements ServiceReference {
+	
+	 /**
+	 * Service Registration attached to the service reference.
+	 */
+	private ServiceRegistrationImpl m_registration = null;
+	 
+	 /**
+	 * 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; }
+
+	/**
+	 * Not supported in composite.
+	 * @see org.osgi.framework.ServiceReference#getBundle()
+	 */
+	public Bundle getBundle() { 
+		throw new UnsupportedOperationException("getUsingBundles is not supported in scope");
+	}
+	
+	/**
+	 * @return the service registration for this service reference.
+	 */
+	public ServiceRegistrationImpl getServiceRegistration() { return m_registration; }
+
+	/**
+	 * @see org.osgi.framework.ServiceReference#getProperty(java.lang.String)
+	 */
+	public Object getProperty(String s) {
+		return m_registration.getProperty(s);
+	}
+
+	/**
+	 * @see org.osgi.framework.ServiceReference#getPropertyKeys()
+	 */
+	public String[] getPropertyKeys() {
+		return m_registration.getPropertyKeys();
+	}
+
+	/**
+	 * Not supported in composite.
+	 * @see org.osgi.framework.ServiceReference#getUsingBundles()
+	 */
+	public Bundle[] getUsingBundles() {
+		throw new UnsupportedOperationException("getUsingBundles is not supported in scope");
+	}
+
+	/**
+	 * @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/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
new file mode 100644
index 0000000..4734c86
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
@@ -0,0 +1,232 @@
+/* 
+ * 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.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 implemenation.
+ * This class is used for in the composition.
+ * @author <a href="mailto:felix-dev@incubator.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;
+
+    /**
+     * 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;
+        m_factory = (m_svcObj instanceof ServiceFactory)
+            ? (ServiceFactory) m_svcObj : null;
+
+        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 hashcode of this reference for
+        // a references to this service in ServiceReference.
+        m_ref = new ServiceReferenceImpl(cm, this);
+    }
+
+    /**
+     * @return true if the service registration is valid.
+     */
+    protected boolean isValid() { return (m_svcObj != null); }
+
+    /**
+     * @see org.osgi.framework.ServiceRegistration#getReference()
+     */
+    public ServiceReference getReference() { return m_ref; }
+
+    /**
+     * @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);
+    }
+
+    /**
+     * @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);
+    }
+
+    /**
+     * Property Keys List.
+     */
+    private transient ArrayList m_list = new ArrayList();
+
+    /**
+     * @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()]);
+        }
+    }
+
+    /**
+     * @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 : serivce 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);
+    }
+
+    /**
+     * @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);
+        }
+	}
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
new file mode 100644
index 0000000..381b16b
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
@@ -0,0 +1,306 @@
+/* 
+ * 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 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:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceRegistry {
+	
+	/**
+	 * Service Id index. 
+	 */
+	private long m_serviceId = 1L;
+	
+	/**
+	 * List of service listeners. 
+	 */
+	private ArrayList m_listeners = new ArrayList(); // ListenerInfo List
+	
+	/**
+	 * List of service registration. 
+	 */
+	private ArrayList 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 {	
+		private ServiceListener m_listener;
+		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()) {
+			return false;
+		} else {
+			reg.ungetService(cm, reg.getService());
+			return true;
+		}
+	}
+
+	/**
+	 * Unregister a service listener.
+	 * @param arg0 : the service listenenr 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 (this) {
+			// Iterate on the service listenner 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 (this) {
+			//	Define filter if expression is not null.
+			Filter filter = null;
+			if (expr != null) { filter = m_bc.createFilter(expr); }
+        
+			ArrayList 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 (this) {
+			try {
+				ServiceReference[] refs = getServiceReferences(clazz, null);
+				if (refs != null) { return refs[0]; } // If the refs != null we are sure that it exist one references or more.
+			} catch (InvalidSyntaxException ex) { System.err.println("Scope Service Registry : Problem when look 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 (this) {
+			// 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
+	 */
+	public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+		synchronized (this) {
+			// 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) {
+		synchronized (this) {
+			ListenerInfo li = new ListenerInfo();
+			li.m_listener = listener; 
+			try {
+				li.m_filter = m_bc.createFilter(filter);
+			} catch (InvalidSyntaxException ex) { System.err.println("Scope Service Registry : Problem when creatin 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) {
+		synchronized (this) {
+			m_regs.remove(reg);
+			fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
+		}
+	}
+	
+	/**
+	 * @return the size of the service registry.
+	 */
+	protected int getSize() {
+		return m_regs.size();
+	}
+	
+	/**
+	 * Reset the service registry.
+	 */
+	protected void reset() {
+		m_serviceId = 1L;
+		m_listeners = new ArrayList();
+		m_regs = new ArrayList();
+	}
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/StringMap.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
new file mode 100644
index 0000000..5800a02
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
@@ -0,0 +1,131 @@
+/* 
+ * 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.
+**/
+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);
+    }
+    
+    /**
+     * @see java.util.TreeMap#put(K, V)
+     */
+    public Object put(Object key, Object value) {
+        return super.put(key.toString(), value);
+    }
+    
+    /**
+     * @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 {
+        private boolean m_isCaseSensitive = true;
+
+        /**
+         * Constructor.
+         * @param b : true to enable the case sensitivity.
+         */
+        public StringComparator(boolean b) {
+            m_isCaseSensitive = b;
+        }
+
+        /**
+         * @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());
+            }
+        }
+
+        /**
+         * @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;
+        }
+        
+        /**
+         * @see java.lang.Object#clone()
+         */
+        public Object clone() {
+        	return this;
+        }
+    }
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
new file mode 100644
index 0000000..697decb
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
@@ -0,0 +1,100 @@
+/* 
+ * 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 java.util.Properties;
+
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Composite Architecture Handler.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ArchitectureHandler extends CompositeHandler implements Architecture {
+
+	/**
+     * Composite Manager.
+     */
+    private CompositeManager m_manager;
+
+    /**
+     * Service Registration of the Architecture service provided by this handler.
+     */
+    private ServiceRegistration m_sr;
+
+    /**
+     * Name of the component.
+     */
+    private String m_name;
+
+    /**
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(CompositeManager im, Element metadata, Dictionary configuration) {
+        if (metadata.containsAttribute("architecture")) {
+            String isArchitectureEnabled = (metadata.getAttribute("architecture")).toLowerCase();
+            if (isArchitectureEnabled.equalsIgnoreCase("true")) { im.register(this); }
+        }
+
+        m_name = (String) configuration.get("name");
+
+        m_manager = im;
+    }
+
+    /**
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
+    public void stop() {
+        try {
+            if (m_sr != null) { m_sr.unregister(); m_sr = null; }
+        } catch (Exception e) { return; }
+    }
+
+    /**
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() {
+        // Unregister the service if already registred
+        if (m_sr != null) { m_sr.unregister(); }
+
+        // Register the ManagedService
+        BundleContext bc = m_manager.getContext();
+        Dictionary properties = new Properties();
+        properties.put("Component.Type", m_manager.getComponentDescription().getName());
+        properties.put(Constants.SERVICE_PID, m_name);
+
+        m_sr = bc.registerService(Architecture.class.getName(), this, properties);
+    }
+
+    /**
+     * @see org.apache.felix.ipojo.architecture.Architecture#getComponentDescription()
+     */
+    public InstanceDescription getInstanceDescription() {
+        return m_manager.getInstanceDescription();
+    }
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
new file mode 100644
index 0000000..df213dc
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
@@ -0,0 +1,77 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.composite.service.importer;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+
+/**
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ImportExportDescription extends HandlerDescription {
+	
+	private List m_imports;
+	private List m_exports;
+
+	/**
+	 * Constructor.
+	 * @param name
+	 * @param isValid
+	 * @param importers
+	 * @param exporters
+	 */
+	public ImportExportDescription(String name, boolean isValid, List importers, List exporters) {
+		super(name, isValid);
+		m_imports = importers;
+		m_exports = exporters;
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+	 */
+	public String getHandlerInfo() {
+		String s = "";
+		for (int i = 0; i < m_imports.size(); i++) {
+			ServiceImporter imp = (ServiceImporter) m_imports.get(i);
+			if (imp.isSatisfied()) {
+				s += "\t Specification " + imp.getSpecification() + " provided by \n \t";
+				for (int j = 0; j < imp.getProviders().size(); j++) {
+					String prov = (String) imp.getProviders().get(j);
+					s += prov + " ";
+				}	
+			} else {
+				s += "\t Specification " + imp.getSpecification() + " is not statisfied \n";
+			}
+		}
+		for (int i = 0; i < m_exports.size(); i++) {
+			ServiceExporter exp = (ServiceExporter) m_exports.get(i);
+			if (exp.isSatisfied()) {
+				s += "\t Specification " + exp.getSpecification() + " is exported or optional";
+			} else {
+				s += "\t Specification " + exp.getSpecification() + " is not exported";
+			}
+		}
+		return s;
+		
+	}
+	
+	
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
new file mode 100644
index 0000000..cf55240
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
@@ -0,0 +1,241 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.composite.service.importer;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.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 importation and the exportation of services from / to the parent context.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ImportExportHandler extends CompositeHandler {
+	
+	/**
+	 * Composite Manager.
+	 */
+	private CompositeManager m_manager;
+	
+	/**
+	 * Service Scope. 
+	 */
+	private ServiceContext m_scope;
+	
+	/**
+	 * Parent context. 
+	 */
+	private BundleContext m_context;
+	
+	/**
+	 * List of importers. 
+	 */
+	private List m_importers = new ArrayList();
+	
+	/**
+	 * List of exporters.
+	 */
+	private List m_exporters = new ArrayList(); 
+	
+	/**
+	 * Is the handler valid ?
+	 */
+	private boolean m_valid;
+
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+	 */
+	public void configure(CompositeManager im, Element metadata, Dictionary conf) {
+		m_manager = im;
+		m_context = im.getContext();
+		m_scope = m_manager.getServiceContext();
+		
+		Element[] imp = metadata.getElements("import");
+		Element[] exp = metadata.getElements("export");
+		
+		for (int i = 0; i < imp.length; i++) {
+			boolean optional = false;
+			boolean aggregate = false;
+			String specification = null;
+			
+			if (!imp[i].containsAttribute("specification")) { // Malformed import
+				im.getFactory().getLogger().log(Logger.ERROR, "Malformed import : the specification attribute is mandatory");
+			} else {
+				specification = imp[i].getAttribute("specification");
+				String filter = "(&(objectClass=" + specification + ")(!(service.pid=" + m_manager.getInstanceName() + ")))"; // Cannot import yourself
+				if (imp[i].containsAttribute("optional") && imp[i].getAttribute("optional").equalsIgnoreCase("true")) { optional = true; }
+				if (imp[i].containsAttribute("aggregate") && imp[i].getAttribute("aggregate").equalsIgnoreCase("true")) { aggregate = true; }
+				if (imp[i].containsAttribute("filter")) { 
+					String classnamefilter = "(objectClass=" + specification + ")";
+			        filter = "";
+			        if (!imp[i].getAttribute("filter").equals("")) {
+			            filter = "(&" + classnamefilter + imp[i].getAttribute("filter") + ")";
+			        } else {
+			            filter = classnamefilter;
+			        }
+				}
+				ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, this);
+				m_importers.add(si);
+			}
+		}
+		
+		for (int i = 0; i < exp.length; i++) {
+			boolean optional = false;
+			boolean aggregate = false;
+			String specification = null;
+			
+			if (!exp[i].containsAttribute("specification")) { // Malformed exports
+				im.getFactory().getLogger().log(Logger.ERROR, "Malformed exports : the specification attribute is mandatory");
+			} else {
+				specification = exp[i].getAttribute("specification");
+				String filter = "(objectClass=" + specification + ")";
+				if (exp[i].containsAttribute("optional") && exp[i].getAttribute("optional").equalsIgnoreCase("true")) { optional = true; }
+				if (exp[i].containsAttribute("aggregate") && exp[i].getAttribute("aggregate").equalsIgnoreCase("true")) { aggregate = true; }
+				if (exp[i].containsAttribute("filter")) { 
+					String classnamefilter = "(objectClass=" + specification + ")";
+			        filter = "";
+			        if (!imp[i].getAttribute("filter").equals("")) {
+			            filter = "(&" + classnamefilter + exp[i].getAttribute("filter") + ")";
+			        } else {
+			            filter = classnamefilter;
+			        }
+			    }
+				ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, this);
+				// Update the componenet type description
+				
+				m_manager.getComponentDescription().addProvidedServiceSpecification(specification);
+				m_exporters.add(si);
+			}
+		}
+		
+		if (m_importers.size() > 0 || m_exporters.size() > 0) {
+			im.register(this);
+		}
+	}
+
+	/**
+	 * @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.configure(m_context, m_scope);
+			si.start();
+		}
+		
+		for (int i = 0; i < m_exporters.size(); i++) {
+			ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+			se.configure(m_scope, m_context);
+			se.start();
+		}
+		
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#stop()
+	 */
+	public void stop() {
+		for (int i = 0; i < m_importers.size(); i++) {
+			ServiceImporter si = (ServiceImporter) m_importers.get(i);
+			si.stop();
+		}
+		
+		for (int i = 0; i < m_exporters.size(); i++) {
+			ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+			se.stop();
+		}
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+	 */
+	public boolean isValid() {
+		for (int i = 0; i < m_importers.size(); i++) {
+			ServiceImporter si = (ServiceImporter) m_importers.get(i);
+			if (!si.isSatisfied()) { m_valid = false; return false; }
+		}
+		
+		for (int i = 0; i < m_exporters.size(); i++) {
+			ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+			if (!se.isSatisfied()) { m_valid = false; return false; }
+		}
+	
+		m_valid = true;
+		return true;
+	}
+
+	/**
+	 * Notify the handler that an importer is no more valid.
+	 * @param importer : the implicated importer.
+	 */
+	protected void invalidating(ServiceImporter importer) {
+		//	An import is no more valid
+		if (m_valid) { m_manager.checkInstanceState(); }
+		
+	}
+
+	/**
+	 * Notify the handler that an importer becomes valid.
+	 * @param importer : the implicated importer.
+	 */
+	protected void validating(ServiceImporter importer) {
+		// An import becomes valid
+		if (!m_valid && isValid()) { m_manager.checkInstanceState(); }
+		
+	}
+
+	/**
+	 * Notify the handler that an exporter becomes invalid.
+	 * @param exporter : the impcated exporter.
+	 */
+	protected void invalidating(ServiceExporter exporter) {
+		// An import is no more valid
+		if (m_valid) { m_manager.checkInstanceState(); }
+		
+	}
+
+	/**
+	 * Notify the handler that an exporter becomes valid.
+	 * @param exporter : the impcated exporter.
+	 */
+	protected void validating(ServiceExporter exporter) {
+		// An import becomes valid
+		if (!m_valid && isValid()) { m_manager.checkInstanceState(); }
+		
+	}
+	
+	/**
+	 * @return the attached composite manager.
+	 */
+	protected CompositeManager getManager() { return m_manager; }
+	
+	
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+	 */
+	public HandlerDescription getDescription() { return new ImportExportDescription(this.getClass().getName(), isValid(), m_importers, m_exporters); }
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
new file mode 100644
index 0000000..0b8b570
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
@@ -0,0 +1,301 @@
+/* 
+ * 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.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:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceExporter implements ServiceListener {
+	
+	private BundleContext m_destination;
+	private ServiceContext m_origin;
+	
+	private String m_specification;
+	private Filter m_filter;
+	private String m_filterStr;
+	
+	private boolean m_aggregate = false;
+	private boolean m_optional = false;
+	
+	private ImportExportHandler m_handler;
+	
+	private boolean m_isValid;
+	
+	private class Record {
+		private ServiceReference m_ref;
+		private ServiceRegistration m_reg;
+		private Object m_svcObject;
+	}
+	
+	private List/*<Record>*/ m_records = new ArrayList()/*<Record>*/;
+	
+	/**
+	 * Constructor.
+	 * @param specification
+	 * @param filter
+	 * @param multiple
+	 * @param optional
+	 * @param from
+	 * @param to
+	 * @param exp
+	 */
+	public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to, ImportExportHandler 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;
+	}
+	
+	/**
+	 * @param specification
+	 * @param filter
+	 * @param multiple
+	 * @param optional
+	 * @param exp
+	 */
+	public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ImportExportHandler exp) {
+		this.m_handler = exp;
+		this.m_filterStr = filter;
+		this.m_aggregate = multiple;
+		this.m_specification = specification;
+		this.m_optional = optional;
+	}
+	
+	/**
+	 * @param from
+	 * @param to
+	 */
+	public void configure(ServiceContext from, BundleContext to) {
+		this.m_destination = to;
+		this.m_origin = from;
+		try {
+			this.m_filter = to.createFilter(m_filterStr);
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); return; }
+	}
+	
+	/**
+	 * 
+	 */
+	public void start() {
+		try {
+			ServiceReference[] refs = m_origin.getServiceReferences(m_specification, null);
+			if (refs != null) {
+				for (int i = 0; i < refs.length; i++) {
+					if (m_filter.match(refs[i])) {
+						Record rec = new Record();
+						rec.m_ref = refs[i];
+						m_records.add(rec);
+					}
+				}
+			}
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+		
+		// Publish available services 
+		if (m_records.size() > 0) {
+			if (m_aggregate) {
+				for (int i = 0; i < m_records.size(); i++) {
+					Record rec = (Record) m_records.get(i);
+					rec.m_svcObject = m_origin.getService(rec.m_ref);
+					rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+				}
+			} else {
+				Record rec = (Record) m_records.get(0);
+				rec.m_svcObject = m_origin.getService(rec.m_ref);
+				rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+			}
+		}
+		
+		// Register service listener
+		try {
+			m_origin.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+		
+		m_isValid = isSatisfied();
+	}
+	
+	/**
+	 * @param ref
+	 * @return
+	 */
+	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(Constants.SERVICE_PID, m_handler.getManager().getInstanceName());
+		prop.put("factory.pid", m_handler.getManager().getFactory().getFactoryName());
+
+		return prop;
+	}
+	
+	/**
+	 * 
+	 */
+	public 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();
+		
+	}
+	
+	/**
+	 * @return
+	 */
+	public boolean isSatisfied() {
+		return m_optional || m_records.size() > 0;
+	}
+	
+	/**
+	 * @param ref
+	 * @return
+	 */
+	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;
+	}
+	
+	/**
+	 * @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());
+				}
+			}
+		}
+	}
+	
+	/**
+	 * @param ref
+	 */
+	private void arrivalManagement(ServiceReference ref) {
+		// Check if the new service match
+		if (m_filter.match(ref)) {
+			// Add it to the record list
+			Record rec = new Record();
+			rec.m_ref = ref;
+			m_records.add(rec);
+			// Publishing ?
+			if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
+				rec.m_svcObject = m_origin.getService(rec.m_ref);
+				rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+			}			
+			// Compute the new state 
+			if (!m_isValid && isSatisfied()) {
+				m_isValid = true;
+				m_handler.validating(this);
+			}
+		}
+	}
+	
+	/**
+	 * @param ref
+	 */
+	private void departureManagement(ServiceReference ref) {
+		List l = getRecordsByRef(ref);
+		for (int i = 0; i < l.size(); i++) { // Stop the implied record
+			Record rec = (Record) l.get(i);
+			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_handler.invalidating(this);
+			}
+		}
+	}
+	
+	/**
+	 * @return the exported specification.
+	 */
+	protected String getSpecification() {
+		return m_specification;
+	}
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
new file mode 100644
index 0000000..79ef6f7
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
@@ -0,0 +1,316 @@
+/* 
+ * 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.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;
+
+/**
+ * Import a service form the parent to the internal service registry. 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceImporter implements ServiceListener {
+	
+	private ServiceContext m_destination;
+	private BundleContext m_origine;
+	
+	private String m_specification;
+	private Filter m_filter;
+	private String m_filterStr;
+	
+	private boolean m_aggregate = false;
+	private boolean m_optional = false;
+	
+	private boolean m_isValid;
+	
+	private ImportExportHandler m_handler;
+	
+	private class Record {
+		private ServiceReference m_ref;
+		private ServiceRegistration m_reg;
+		private Object m_svcObject;
+	}
+	
+	private List/*<Record>*/ m_records = new ArrayList()/*<Record>*/;
+	
+	/**
+	 * Constructor.
+	 * @param specification : targetted 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 in : handler
+	 */
+	public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to, ImportExportHandler in) {
+		this.m_destination = to;
+		this.m_origine = from;
+		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;
+	}
+	
+	/**
+	 * Constructor.
+	 * @param specification : targetted specification
+	 * @param filter : LDAP filter
+	 * @param multiple : should the importer imports several services ?
+	 * @param optional : is the import optional ?
+	 * @param in : handler
+	 */
+	public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, ImportExportHandler in) {
+		this.m_filterStr = filter;
+		this.m_aggregate = multiple;
+		this.m_filterStr = filter;
+		this.m_specification = specification;
+		this.m_optional = optional;
+		this.m_handler = in;
+	}
+	
+	/**
+	 * Configure the origin and the destination of the import.
+	 * @param from : origine (parent)
+	 * @param to : destination (internal scope)
+	 */
+	public void configure(BundleContext from, ServiceContext to) {
+		this.m_destination = to;
+		this.m_origine = from;
+		try {
+			this.m_filter = from.createFilter(m_filterStr);
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); return; }
+	}
+	
+	/**
+	 * Start method to begin the import.
+	 */
+	public void start() {
+		try {
+			ServiceReference[] refs = m_origine.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_origine.getService(rec.m_ref);
+					rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+				}
+			} else {
+				Record rec = (Record) m_records.get(0);
+				rec.m_svcObject = m_origine.getService(rec.m_ref);
+				rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+			}
+		}
+		
+		// Register service listener
+		try {
+			m_origine.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+		
+		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_origine.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_origine.ungetService(rec.m_ref);
+				rec.m_ref = null;
+			}
+		}
+		
+		m_records.clear();
+		
+	}
+	
+	/**
+	 * @return true if the import is satisfied.
+	 */
+	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;
+	}
+	
+	/**
+	 * @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 consitent service.
+	 * @param ref : the arrival service reference
+	 */
+	private void arrivalManagement(ServiceReference ref) {
+		//	Check if the new service match
+		if (m_filter.match(ref)) {
+			// Add it to the record list
+			Record rec = new Record();
+			rec.m_ref = ref;
+			m_records.add(rec);
+			// Publishing ?
+			if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
+				rec.m_svcObject = m_origine.getService(rec.m_ref);
+				rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+			}			
+			// Compute the new state 
+			if (!m_isValid && isSatisfied()) {
+				m_isValid = true;
+				m_handler.validating(this);
+			}
+		}
+	}
+	
+	/**
+	 * Manage the departure of a used reference.
+	 * @param ref : the leaving reference
+	 */
+	private void departureManagement(ServiceReference ref) {
+		List l = getRecordsByRef(ref);
+		for (int i = 0; i < l.size(); i++) { // Stop the implied record
+			Record rec = (Record) l.get(i);
+			if (rec.m_reg != null) {
+				rec.m_svcObject = null;
+				rec.m_reg.unregister();
+				rec.m_reg = null;
+				m_origine.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_origine.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);
+			}
+		}
+	}
+	
+	/**
+	 * @return the targetted specification.
+	 */
+	public String getSpecification() { return m_specification; }
+		
+	/**
+	 * @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(Constants.SERVICE_PID));
+		}
+		return l;
+		
+	}
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
new file mode 100644
index 0000000..598faa3
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
@@ -0,0 +1,73 @@
+/* 
+ * 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.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Description of the Service Instantiator Handler.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceInstantiatorDescription extends HandlerDescription {
+	
+	/**
+	 * List of managed service instances.
+	 */
+	private List m_instances;
+
+	/**
+	 * Constructor.
+	 * @param arg0 : name of the handler
+	 * @param arg1 : validity of the handler
+	 * @param insts : list of service instance
+	 */
+	public ServiceInstantiatorDescription(String arg0, boolean arg1, List insts) {
+		super(arg0, arg1);
+		m_instances = insts;
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+	 */
+	public String getHandlerInfo() {
+		String r = "";
+		for (int i = 0; i < m_instances.size(); i++) {
+			SvcInstance inst = (SvcInstance) m_instances.get(i);
+			HashMap 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  && o instanceof ComponentInstance) {
+					r += "\t Specification " + inst.getSpecification() + " instantiated from " + ((ComponentInstance) o).getComponentDescription().getName() + " \n";
+				}
+			}
+		}
+		return r;
+	}
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
new file mode 100644
index 0000000..1810c5f
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
@@ -0,0 +1,158 @@
+/* 
+ * 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.CompositeManager;
+import org.apache.felix.ipojo.Factory;
+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:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceInstantiatorHandler extends CompositeHandler {
+	
+	/**
+	 * Composite Manager. 
+	 */
+	private CompositeManager m_manager;
+	
+	/**
+	 * Is the handler valid ?
+	 */
+	private boolean m_isValid = false;
+	
+	/**
+	 * List of instances to manage.
+	 */
+	private List/*<SvcInstance>*/ m_instances = new ArrayList();
+
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+	 */
+	public void configure(CompositeManager im, Element metadata, Dictionary conf) {
+		m_manager = im;
+		Element[] services = metadata.getElements("service");
+		for (int i = 0; i < services.length; i++) {
+			String spec = services[i].getAttribute("specification");
+			String filter = "(objectClass=" + Factory.class.getName() + ")";
+			if (services[i].containsAttribute("filter")) { 
+				String classnamefilter = "(&(objectClass=" + Factory.class.getName() + ")(!(service.pid=" + m_manager.getInstanceName() + ")))";  // Cannot instantaite yourself
+		        filter = "";
+		        if (!services[i].getAttribute("filter").equals("")) {
+		            filter = "(&" + classnamefilter + services[i].getAttribute("filter") + ")";
+		        } else {
+		            filter = classnamefilter;
+		        }
+			}
+			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);
+			}
+			boolean agg = false;
+			if (services[i].containsAttribute("aggregate") && services[i].getAttribute("aggregate").equalsIgnoreCase("true")) { agg = true; }
+			boolean opt = false;
+			if (services[i].containsAttribute("optional") && services[i].getAttribute("optional").equalsIgnoreCase("true")) { opt = true; }
+			SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, filter);
+			m_instances.add(inst);
+		}
+		if (m_instances.size() > 0) {
+			m_manager.register(this);
+		}
+	}
+
+	/**
+	 * @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 = isValid();
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+	 */
+	public boolean isValid() {
+		for (int i = 0; i < m_instances.size(); i++) {
+			SvcInstance inst = (SvcInstance) m_instances.get(i);
+			if (!inst.isSatisfied()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * @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 (isValid()) { m_manager.checkInstanceState(); }
+			m_isValid = true;
+		}
+	}
+	
+	/**
+	 * A service instance becomes invalid.
+	 */
+	public void invalidate() {
+		if (m_isValid) {
+			if (!isValid()) { m_manager.checkInstanceState(); }
+			m_isValid = false;
+		}
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+	 */
+	public HandlerDescription getDescription() {
+		return new ServiceInstantiatorDescription(this.getClass().getName(), isValid(), m_instances);
+	}
+	
+	/**
+	 * @return the composite manager.
+	 */
+	protected CompositeManager getManager() { return m_manager; }
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
new file mode 100644
index 0000000..848d73f
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
@@ -0,0 +1,347 @@
+/* 
+ * 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.Set;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Manage a service instantiation.
+ * This service create componenet instance providing the required service specification.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class SvcInstance implements ServiceListener {
+	
+	/**
+	 * 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 HashMap /*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;
+	
+	/**
+	 * Parent context.
+	 */
+	//private BundleContext m_parent;
+	
+	/**
+	 * True if the service instantiation is valid.
+	 */
+	private boolean m_isValid = false;
+	
+	/**
+	 * String form of the factory filter.
+	 */
+	private String m_filterStr;
+	
+	/**
+	 * Name of the last create instance.
+	 */
+	private long m_index = 0;
+	
+	/**
+	 * Constructor.
+	 * @param h : the handler.
+	 * @param spec : required specification.
+	 * @param conf : instance configuration.
+	 * @param isAgg : is the svc instance an aggregate service ?
+	 * @param isOpt : is the svc instance optional ?
+	 */
+	public SvcInstance(ServiceInstantiatorHandler h, String spec, Dictionary conf, boolean isAgg, boolean isOpt, String filt) {
+		m_handler = h;
+		m_context = h.getManager().getServiceContext();
+		//m_parent = h.getManager().getContext();
+		m_specification = spec;
+		m_configuration = conf;
+		m_isAggregate = isAgg;
+		m_isOptional = isOpt;
+		m_filterStr = filt;
+	}
+	
+	/**
+	 * Start the service instance.
+	 * @param sc
+	 */
+	public void start() {
+		initFactoryList();
+		// Register factory listener
+		try {
+			m_context.addServiceListener(this, m_filterStr);
+		} catch (InvalidSyntaxException e) { 
+			e.printStackTrace(); // Should not happens
+		}
+
+		// Init the instances 
+		if (m_usedRef.size() > 0) {
+			Set keys = m_usedRef.keySet();
+			Iterator it = keys.iterator();
+			if (m_isAggregate) {
+				while (it.hasNext()) {
+					ServiceReference ref = (ServiceReference) it.next();
+					createInstance(ref);
+				}
+			} else {
+				ServiceReference ref = (ServiceReference) it.next();
+				createInstance(ref);
+			}
+		}
+		m_isValid = isSatisfied();
+	}
+	
+	/**
+	 * Stop the service instance.
+	 */
+	public void stop() {
+		m_context.removeServiceListener(this);
+		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).stop();
+			}
+		}
+		m_usedRef.clear();
+		m_isValid = false;
+	}
+	
+	/**
+	 * @return true if at least one instance is created.
+	 */
+	private boolean isAnInstanceCreated() {
+		Set keys = m_usedRef.keySet();
+		Iterator it = keys.iterator();
+		ServiceReference ref = (ServiceReference) it.next();
+		Object o = m_usedRef.get(ref);
+		return o != null;
+	}
+	
+	/**
+	 * Create an instance for the given reference.
+	 */
+	private void createInstance(ServiceReference ref) {
+		try {
+			Factory factory = (Factory) m_context.getService(ref);
+			ComponentInstance instance = factory.createComponentInstance(m_configuration);
+			m_usedRef.put(ref, instance);
+			m_context.ungetService(ref);
+		} catch (UnacceptableConfiguration e) {
+			System.err.println("A matching factory (" + ref.getProperty("service.pid") + ") seems to refuse the given configuration : " + e.getMessage());
+		}
+	}
+	
+	/**
+	 * 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);
+			ComponentInstance instance = factory.createComponentInstance(m_configuration);
+			m_usedRef.put(ref, instance);
+			m_context.ungetService(ref);
+		} catch (UnacceptableConfiguration e) {
+			System.err.println("A matching factory seems to refuse the given configuration : " + e.getMessage());
+		}
+	}
+	
+	/**
+	 * Kill an instance (if exist).
+	 */
+	private void stopInstance(ServiceReference ref) {
+		Object o = m_usedRef.get(ref);
+		if (o != null) {
+			((ComponentInstance) o).stop();
+		}
+	}
+
+
+	/**
+	 * Init the list of available factory.
+	 */
+	public void initFactoryList() {
+		// Init factory list
+		try {
+			ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), m_filterStr);
+			if (refs == null) { return; }
+			for (int i = 0; i < refs.length; i++) {
+				ServiceReference ref = refs[i];
+				Factory fact = (Factory) m_context.getService(ref);
+				// Check provided spec & conf
+				if (match(fact)) {
+					m_usedRef.put(ref, null);
+				}
+				fact = null;
+				m_context.ungetService(ref);
+			}
+		} catch (InvalidSyntaxException e) {
+			e.printStackTrace(); // Should not happen
+		}
+	}
+	
+	/**
+	 * @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) {
+		// Check if the factory can provide the spec
+		for (int i = 0; i < fact.getComponentDescription().getprovidedServiceSpecification().length; i++) {
+			if (fact.getComponentDescription().getprovidedServiceSpecification()[i].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.
+				if (m_configuration.get("name") == null) {
+					m_configuration.put("name", this.toString() + "-" + m_index);
+					m_index++;
+				}
+				
+				// Check the acceptability.
+				return (fact.isAcceptable(m_configuration));
+			}
+		}
+		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) {
+		PropertyDescription[] props = factory.getComponentDescription().getProperties();
+		for (int i = 0; i < props.length; i++) {
+			if (props[i].getName().equalsIgnoreCase(name)) { return true; }
+		}
+		if (name.equalsIgnoreCase("name")) { return true; } // Skip the name property
+		return false;
+	}
+
+	/**
+	 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+	 */
+	public void serviceChanged(ServiceEvent ev) {
+		if (ev.getType() == ServiceEvent.REGISTERED) {
+			// Check the matching
+			Factory fact = (Factory) m_context.getService(ev.getServiceReference());
+			if (match(fact)) {
+				m_usedRef.put(ev.getServiceReference(), null);
+				if (m_isAggregate) { // Create an instance for the new factory
+					createInstance(ev.getServiceReference());
+					if (!m_isValid) { m_isValid = true; m_handler.validate(); }
+				} else { 
+					if (!isAnInstanceCreated()) { createInstance(ev.getServiceReference()); }
+					if (!m_isValid) { m_isValid = true; m_handler.validate(); }
+				}
+			}
+			fact = null;
+			m_context.ungetService(ev.getServiceReference());
+			return;
+		}
+		if (ev.getType() == ServiceEvent.UNREGISTERING) {
+			// Remove the ref is contained
+			Object o = m_usedRef.remove(ev.getServiceReference());
+			if (o != null) { 
+				stopInstance(ev.getServiceReference());
+				if (m_usedRef.size() > 0) {
+					if (!m_isAggregate) {
+						createNextInstance(); // Create an instance with another factory
+					} 
+				} else { // No more candidate
+					if (!m_isOptional) { m_isValid = false; m_handler.invalidate(); }
+				}
+			}
+		}
+	}
+
+	/**
+	 * @return the required specification.
+	 */
+	public String getSpecification() {
+		return m_specification;
+	}
+	
+	/**
+	 * @return the map of used references.
+	 */
+	protected HashMap getUsedReferences() { 
+		return m_usedRef;
+	}
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
index ccd81c7..64bc089 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
@@ -296,7 +296,6 @@
 
             // If a service goes way.
             if (event.getType() == ServiceEvent.UNREGISTERING) {
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] A service is gone -> " + event.getServiceReference().getBundle());
                 if (containsSR(event.getServiceReference())) { departureManagement(event.getServiceReference()); }
                 return;
             }
@@ -311,12 +310,10 @@
             // If a service is modified
             if (event.getType() == ServiceEvent.MODIFIED) {
                 if (m_filter.match(event.getServiceReference())) {
-                    m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] A service with a filter matching is arrived -> " + event.getServiceReference().getBundle());
                     if (!containsSR(event.getServiceReference())) { 
                     	arrivalManagement(event.getServiceReference()); 
                     }
                 } else {
-                    m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] A service with a filter matching has gone -> " + event.getServiceReference().getBundle());
                     if (containsSR(event.getServiceReference())) { 
                     	departureManagement(event.getServiceReference()); 
                     }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java b/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
index 23adeb1..58ff68a 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
@@ -42,11 +42,23 @@
     private Element[] m_elements = new Element[0];
 
     /**
-     * @return the component metadata.
+     * @return the component metadata (composite & component).
      * @throws ParseException when a parsing error occurs
      */
     public Element[] getComponentsMetadata() throws ParseException {
-        return m_elements[0].getElements("Component");
+        Element[] components = m_elements[0].getElements("Component");
+        Element[] composites = m_elements[0].getElements("Composite");
+        Element[] all = new Element[components.length + composites.length];
+        int l = 0;
+        for (int i = 0; i < components.length; i++) {
+        	all[l] = components[i];
+        	l++;
+        }
+        for (int i = 0; i < composites.length; i++) {
+        	all[l] = composites[i];
+        	l++;
+        }
+        return all;
     }
 
     /**
@@ -152,7 +164,6 @@
         //Add the ipojo element inside the element list
         addElement(new Element("iPOJO", ""));
         parseElements(componentClassesStr.trim());
-
     }
 
     /**