Initial commit of iPOJO source, which was accepted as a subproject
contribution by a vote.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@414287 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.ipojo.arch/pom.xml b/org.apache.felix.ipojo.arch/pom.xml
new file mode 100644
index 0000000..df6a7cc
--- /dev/null
+++ b/org.apache.felix.ipojo.arch/pom.xml
@@ -0,0 +1,43 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>ipojo-bundle</packaging>
+  <name>Apache Felix iPOJO Arch Command</name>
+  <version>0.6.0-SNAPSHOT</version>
+  <artifactId>org.apache.felix.ipojo.arch</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.ipojo</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.shell</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>${pom.groupId}</groupId>
+        <artifactId>org.apache.felix.ipojo.plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>iPOJO Arch Command</bundleName>
+            <bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
+            <bundleDescription>Architecture Shell Command (arch)</bundleDescription>
+            <iPOJOMetadata>metadata.xml</iPOJOMetadata>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/org.apache.felix.ipojo.arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java b/org.apache.felix.ipojo.arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
new file mode 100644
index 0000000..ae3cf61
--- /dev/null
+++ b/org.apache.felix.ipojo.arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
@@ -0,0 +1,91 @@
+package org.apache.felix.ipojo.arch;
+
+
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.DependencyDescription;
+import org.apache.felix.ipojo.architecture.ProvidedServiceDescription;
+import org.apache.felix.ipojo.architecture.State;
+import org.ungoverned.osgi.service.shell.Command;
+
+
+/**
+ * Implementation of the archi command printing the actual architecture.
+ * @author Clement Escoffier
+ */
+public class ArchCommandImpl implements Command {
+
+	/**
+	 * List of archi service
+	 */
+	private Architecture archiService[];
+
+    /**
+     * @see org.ungoverned.osgi.service.shell.Command#getName()
+     */
+    public String getName() {
+        return "arch";
+    }
+
+    /**
+     * @see org.ungoverned.osgi.service.shell.Command#getUsage()
+     */
+    public String getUsage() {
+        return "arch -> Dispaly architecture information";
+    }
+
+    /**
+     * @see org.ungoverned.osgi.service.shell.Command#getShortDescription()
+     */
+    public String getShortDescription() {
+        return "Architecture command : display the architecture";
+    }
+
+    /**
+     * @see org.ungoverned.osgi.service.shell.Command#execute(java.lang.String, java.io.PrintStream, java.io.PrintStream)
+     */
+    public void execute(String line, PrintStream out, PrintStream err) {
+        synchronized(this) { 
+        	for(int i=0; i < archiService.length; i++) {
+        		ComponentDescription component = archiService[i].getComponentDescription();       
+        		out.println("Component : " + component.getClassName() + " - " + State.printComponentState(component.getState()));
+        		for(int j = 0; j < component.getDependencies().length; j++) {
+        			DependencyDescription dd = component.getDependencies()[j];
+        			out.println("\t Dependency : " + dd.getInterface() + " - " + State.printDependencyState(dd.getState()) + " - Optional : " + dd.isOptional() + " - Multiple : " + dd.isMultiple());
+        			// getUsedServices :
+        			HashMap hm = dd.getUsedServices();
+        			Iterator it = hm.keySet().iterator();
+        			while(it.hasNext()) {
+        				String key = (String) it.next();
+        				out.println("\t\t Used Service : " + key + " - " + hm.get(key));
+        			}
+        		}
+        		for(int j=0;  j < component.getProvideServices().length; j++) {
+        			ProvidedServiceDescription ps = component.getProvideServices()[j];
+        			String spec = "";
+        			for(int k = 0; k < ps.getServiceSpecification().length; k++) {
+        				spec = spec + " " + ps.getServiceSpecification()[k];
+        			}
+        			out.println("\t Provides : " + spec + " - " + State.printProvidedServiceState(ps.getState()));
+        			Enumeration e = ps.getProperties().propertyNames();
+        			while(e.hasMoreElements()) {
+        				Object key = e.nextElement();
+        				out.println("\t\t Service Property : " + key.toString() + " = " + ps.getProperties().getProperty(key.toString()));  
+        			}
+        		}
+        		out.println("\tCreated Instances : ");
+        		for(int j=0;  j < component.getInstances().length; j++) {
+        			out.println("\t\t" + component.getInstances()[j]);
+        		}
+        		
+        		out.print("\n");
+        	}
+        }
+        
+    }
+}
\ No newline at end of file
diff --git a/org.apache.felix.ipojo.arch/src/main/resources/metadata.xml b/org.apache.felix.ipojo.arch/src/main/resources/metadata.xml
new file mode 100644
index 0000000..b0bbbb3
--- /dev/null
+++ b/org.apache.felix.ipojo.arch/src/main/resources/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<iPOJO>
+	<Component className="org.apache.felix.ipojo.arch.ArchCommandImpl">
+		  <Provides interface="org.ungoverned.osgi.service.shell.Command"/>
+		  <Dependency field="archiService" optional="true"/>
+	</Component>
+</iPOJO>
\ No newline at end of file
diff --git a/org.apache.felix.ipojo.metadata/pom.xml b/org.apache.felix.ipojo.metadata/pom.xml
new file mode 100644
index 0000000..13ad0fb
--- /dev/null
+++ b/org.apache.felix.ipojo.metadata/pom.xml
@@ -0,0 +1,12 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>org.apache.felix.ipojo.metadata</artifactId>
+  <packaging>jar</packaging>
+  <version>0.6.0-SNAPSHOT</version>
+  <name>Apache Felix iPOJO Metadata</name>
+</project>
diff --git a/org.apache.felix.ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Attribute.java b/org.apache.felix.ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Attribute.java
new file mode 100644
index 0000000..05cff9f
--- /dev/null
+++ b/org.apache.felix.ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Attribute.java
@@ -0,0 +1,78 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.metadata;
+
+/**
+ * Attribute.
+ * @author Clement Escoffier
+ */
+public class Attribute {
+
+	/**
+	 * Name of the attribute.
+	 */
+	private String m_name;
+
+	/**
+	 * Value of the attribute.
+	 */
+	private String m_value;
+
+	/**
+	 * Namepsace of the attribute.
+	 */
+	private String m_nameSpace;
+
+	/**
+     * Constructor.
+	 * @param name : name of the attribute.
+	 * @param value : value of the attribute.
+	 */
+	public Attribute(String name, String value) {
+		m_name = name.toLowerCase();
+		m_value = value;
+		m_nameSpace = "";
+	}
+
+	/**
+     * Constructor.
+	 * @param name : name of the attribute.
+	 * @param value : value of the attribute.
+	 * @param ns : namespace of the attribute.
+	 */
+	public Attribute(String name, String ns, String value) {
+		m_name = name.toLowerCase();
+		m_value = value;
+		m_nameSpace = ns;
+	}
+
+	/**
+	 * @return the name
+	 */
+	public String getName() { return m_name; }
+
+	/**
+	 * @return the value
+	 */
+	public String getValue() { return m_value; }
+
+	/**
+	 * @return the namespace
+	 */
+	public String getNameSpace() { return m_nameSpace; }
+
+}
diff --git a/org.apache.felix.ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java b/org.apache.felix.ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
new file mode 100644
index 0000000..2effc3a
--- /dev/null
+++ b/org.apache.felix.ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
@@ -0,0 +1,311 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.metadata;
+
+/**
+ * Element.
+ * @author Clement Escoffier
+ */
+public class Element {
+
+	/**
+	 * Name of the element.
+	 */
+	private String m_name;
+
+    /**
+     * Name space of the element.
+     */
+    private String m_nameSpace;
+
+	/**
+	 * List of the attributes of the element.
+	 */
+	private Attribute[] m_attributes = new Attribute[0];
+
+	/**
+	 * List of the subelement of the element.
+	 */
+	private Element[] m_elements = new Element[0];
+
+	/**
+     * Constructor.
+	 * @param name : the name of the element
+     * @pram ns : the namespace of the element
+	 */
+	public Element(String name, String ns) {
+        m_name = name.toLowerCase();
+        m_nameSpace = ns;
+    }
+
+	/**
+	 * @return the sub elements
+	 */
+	public Element[] getElements() { return m_elements; }
+
+	/**
+	 * @return the attributes
+	 */
+	public Attribute[] getAttributes() { return m_attributes; }
+
+	/**
+	 * @return the name of the element
+	 */
+	public String getName() { return m_name; }
+
+    /**
+     * @return the namespace of the element
+     */
+    public String getNameSpace() { return m_nameSpace; }
+
+	/**
+     * Return the value of the attribute given in parameter.
+	 * @param name : the name of the searched attribute
+	 * @return the value of the attrbitue given in parameter, null if the attribute does not exist
+	 */
+	public String getAttribute(String name) {
+		name = name.toLowerCase();
+		for (int i = 0; i < m_attributes.length; i++) {
+			if (m_attributes[i].getName().equals(name)) {
+				return m_attributes[i].getValue();
+			}
+		}
+		System.err.println("[Error in Metadata] The attribute " + name + " does not exist in " + m_name + " [" + m_nameSpace + "]");
+		return null;
+	}
+
+	/**
+	 * Return the value of the attrbitue "name" of the namespace "ns".
+	 * @param name : name of the attribute to find
+	 * @param ns : namespace of the attribute to find
+	 * @return the String value of the attribute, or null if the attribute is not found.
+	 */
+	public String getAttribute(String name, String ns) {
+		name = name.toLowerCase();
+		for (int i = 0; i < m_attributes.length; i++) {
+			if (m_attributes[i].getName().equals(name) && m_attributes[i].getNameSpace().equals(ns)) {
+				return m_attributes[i].getValue();
+			}
+		}
+		System.err.println("[Error in Metadata] The attribute " + name + "[" + ns + "] does not exist in " + m_name + " [" + m_nameSpace + "]");
+		return null;
+	}
+
+	/**
+     * Add a subelement.
+	 * @param elem : the element to add
+	 */
+	public void addElement(Element elem) {
+        for (int i = 0; (m_elements != null) && (i < m_elements.length); i++) {
+            if (m_elements[i] == elem) { return; }
+        }
+
+        if (m_elements != null) {
+            Element[] newElementsList = new Element[m_elements.length + 1];
+            System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
+            newElementsList[m_elements.length] = elem;
+            m_elements = newElementsList;
+        }
+        else { m_elements = new Element[] {elem}; }
+	}
+
+	private static Element[] addElement(Element[] list, Element elem) {
+        if (list != null) {
+            Element[] newElementsList = new Element[list.length + 1];
+            System.arraycopy(list, 0, newElementsList, 0, list.length);
+            newElementsList[list.length] = elem;
+            return newElementsList;
+        }
+        else { return new Element[] {elem}; }
+	}
+
+	/**
+     * Remove a subelement.
+	 * @param elem : the element to remove
+	 */
+	public void removeElement(Element elem) {
+        int idx = -1;
+        for (int i = 0; i < m_elements.length; i++) {
+            if (m_elements[i] == elem) { idx = i; break; }
+        }
+
+        if (idx >= 0) {
+            if ((m_elements.length - 1) == 0) { m_elements = new Element[0]; }
+            else {
+                Element[] newElementsList = new Element[m_elements.length - 1];
+                System.arraycopy(m_elements, 0, newElementsList, 0, idx);
+                if (idx < newElementsList.length) {
+                    System.arraycopy(m_elements, idx + 1, newElementsList, idx, newElementsList.length - idx); }
+                m_elements = newElementsList;
+            }
+        }
+	}
+
+	/**
+     * Add a attribute.
+	 * @param att : the attribute to add
+	 */
+	public void addAttribute(Attribute att) {
+        for (int i = 0; (m_attributes != null) && (i < m_attributes.length); i++) {
+            if (m_attributes[i] == att) { return; }
+        }
+
+        if (m_attributes != null) {
+            Attribute[] newAttributesList = new Attribute[m_attributes.length + 1];
+            System.arraycopy(m_attributes, 0, newAttributesList, 0, m_attributes.length);
+            newAttributesList[m_attributes.length] = att;
+            m_attributes = newAttributesList;
+        }
+        else { m_attributes = new Attribute[] {att}; }
+	}
+
+	/**
+     * Remove an attribute.
+	 * @param att : the attribute to remove
+	 */
+	public void removeAttribute(Attribute att) {
+        int idx = -1;
+        for (int i = 0; i < m_attributes.length; i++) {
+            if (m_attributes[i] == att) { idx = i; break; }
+        }
+
+        if (idx >= 0) {
+            if ((m_attributes.length - 1) == 0) { m_attributes = new Attribute[0]; }
+            else {
+                Attribute[] newAttributesList = new Attribute[m_attributes.length - 1];
+                System.arraycopy(m_attributes, 0, newAttributesList, 0, idx);
+                if (idx < newAttributesList.length) {
+                    System.arraycopy(m_attributes, idx + 1, newAttributesList, idx, newAttributesList.length - idx); }
+                m_attributes = newAttributesList;
+            }
+        }
+	}
+
+	/**
+     * Get the elements array of the element type given in parameter.
+     * This method look for an empty namespace.
+	 * @param name : the type of the element to find (element name)
+	 * @return the resulting element array (empty if the search failed)
+	 */
+	public Element[] getElements(String name) {
+		name = name.toLowerCase();
+		Element[] list = new Element[0];
+		for (int i = 0; i < m_elements.length; i++) {
+			if (m_elements[i].getName().equals(name) && m_elements[i].getNameSpace().equals("")) {
+				list = Element.addElement(list, m_elements[i]);
+			}
+		}
+		return list;
+	}
+
+    /**
+     * Get the elements array of the element type given in parameter.
+     * @param name : the type of the element to find (element name)
+     * @param ns : the namespace of the element
+     * @return the resulting element array (empty if the search failed)
+     */
+    public Element[] getElements(String name, String ns) {
+    	name = name.toLowerCase();
+        Element[] list = new Element[0];
+        for (int i = 0; i < m_elements.length; i++) {
+            if (m_elements[i].getName().equals(name) && m_elements[i].getNameSpace().equals(ns)) {
+                list = Element.addElement(list, m_elements[i]);
+            }
+        }
+        return list;
+    }
+
+	/**
+     * Is the element contains a subelement of the type given in parameter.
+     * This method does not manage the namespace
+	 * @param name : type of the element to check.
+	 * @return true if the element contains an element of the type "name"
+	 */
+	public boolean containsElement(String name) {
+		name = name.toLowerCase();
+		for (int i = 0; i < m_elements.length; i++) {
+			if (m_elements[i].getName().equals(name)) { return true; }
+        }
+		return false;
+	}
+
+    /**
+     * Is the element contains a subelement of the type given in parameter.
+     * This method does not manage the namespace
+     * @param name : type of the element to check.
+     * @return true if the element contains an element of the type "name"
+     */
+    public boolean containsElement(String name, String ns) {
+    	name = name.toLowerCase();
+    	ns = ns.toLowerCase();
+        for (int i = 0; i < m_elements.length; i++) {
+            if (m_elements[i].getName().equals(name) && m_elements[i].getNameSpace().equals(ns)) { return true; }
+        }
+        return false;
+    }
+
+	/**
+     * Is the element contains an attribute of the name given in parameter.
+	 * @param name : name of the element
+	 * @return true if the element contains an attribute of the type "name"
+	 */
+	public boolean containsAttribute(String name) {
+		name = name.toLowerCase();
+		for (int i = 0; i < m_attributes.length; i++) {
+			if (m_attributes[i].getName().equals(name)) { return true; }
+        }
+		return false;
+	}
+
+	/**
+	 * @return the first-order namespaces list of the current element. First-order namespace are namespace of the element attribute and namespaces of its direct sub-element.
+	 */
+	public String[] getNamespaces() {
+		String[] ns = new String[0];
+
+		// Look for each direct sub-element
+		for (int i = 0; i < m_elements.length; i++) {
+			boolean found = false;
+			for (int j = 0; !found && j < ns.length; j++) {
+				if (ns[j].equals(m_elements[i].getNameSpace())) { found = true; }
+			}
+			if (!found) {
+				String[] newNSList = new String[ns.length + 1];
+				System.arraycopy(ns, 0, newNSList, 0, ns.length);
+				newNSList[ns.length] = m_elements[i].getNameSpace();
+				ns = newNSList;
+			}
+		}
+
+		// Look for each attribute
+		for (int i = 0; i < m_attributes.length; i++) {
+			boolean found = false;
+			for (int j = 0; !found && j < ns.length; j++) {
+				if (ns[j].equals(m_attributes[i].getNameSpace())) { found = true; }
+			}
+			if (!found) {
+				String[] newNSList = new String[ns.length + 1];
+				System.arraycopy(ns, 0, newNSList, 0, ns.length);
+				newNSList[ns.length] = m_attributes[i].getNameSpace();
+				ns = newNSList;
+			}
+		}
+
+		return ns;
+	}
+
+}
diff --git a/org.apache.felix.ipojo.plugin/pom.xml b/org.apache.felix.ipojo.plugin/pom.xml
new file mode 100644
index 0000000..0e476d8
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/pom.xml
@@ -0,0 +1,54 @@
+<project>
+  <parent>
+    <artifactId>felix</artifactId>
+    <groupId>org.apache.felix</groupId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>org.apache.felix.ipojo.plugin</artifactId>
+  <version>0.6.0-SNAPSHOT</version>
+  <name>Apache Felix iPOJO Maven Plugin</name>
+  <packaging>maven-plugin</packaging>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-archiver</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>1.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>kxml2</groupId>
+      <artifactId>kxml2</artifactId>
+      <version>2.2.2</version>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm</artifactId>
+      <version>2.2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>xerces</groupId>
+      <artifactId>xercesImpl</artifactId>
+      <version>2.4.0</version>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
new file mode 100644
index 0000000..19afa78
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
@@ -0,0 +1,57 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.manipulation;
+
+/**
+ * Store properties for the manipulation process.
+ * @author Clement Escoffier
+ *
+ */
+public class ManipulationProperty {
+
+	/**
+	 * iPOJO Package name.
+	 */
+	protected static final String IPOJO_PACKAGE_NAME = "org.apache.felix.ipojo";
+
+	/**
+	 * Activator internal package name.
+	 */
+	protected static final String IPOJO_INTERNAL_PACKAGE_NAME = "org/apache/felix/ipojo/";
+
+	/**
+	 * Ipojo internal package name for internal descriptor.
+	 */
+	protected static final String IPOJO_INTERNAL_DESCRIPTOR = "L" + IPOJO_INTERNAL_PACKAGE_NAME;
+
+	/**
+	 * Helper array for bytecode manipulation of primitive type.
+	 */
+	protected static final String[][] PRIMITIVE_BOXING_INFORMATION =
+		new String[][] {
+		{"V", "ILLEGAL", "ILLEGAL"}, // Void type [0]
+		{"Z", "java/lang/Boolean", "booleanValue"}, // boolean [1]
+		{"C", "java/lang/Character", "charValue"}, // char [2]
+		{"B", "java/lang/Byte", "byteValue"}, // byte [3]
+		{"S", "java/lang/Short", "shortValue"}, // short [4]
+		{"I", "java/lang/Integer", "intValue"}, // int [5]
+		{"F", "java/lang/Float", "floatValue"}, // float [6]
+		{"J", "java/lang/Long", "longValue"}, // long [7]
+		{"D", "java/lang/Double", "doubleValue"} // double [8]
+	};
+
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
new file mode 100644
index 0000000..5f9537d
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
@@ -0,0 +1,115 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.manipulation;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.plugin.IpojoPluginConfiguration;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+
+/**
+ * iPOJO Bytecode Manipulator.
+ * @author Clement Escoffier
+ *
+ */
+public class Manipulator {
+	/**
+	 * Store the visited fields : [name fo the field, type of the field].
+	 */
+	private HashMap m_fields = new HashMap();
+
+	/**
+	 * Store the interface implemented by the class.
+	 */
+	private String[] m_interfaces = new String[0];
+
+	/**
+	 * Return the hashmap [name of the field, type of the field].
+	 * This information is found when the class is manipulated
+	 * It is a clone of the original hashmap to avoid modification by handlers
+	 * @return the hashmap [name of the field, type of the field].
+	 */
+	public HashMap getFields() {
+		return (HashMap)m_fields.clone();
+	}
+
+	/**
+	 * Return the hashmap [name of the field, type of the field].
+	 * This information is found when the class is manipulated
+	 * It is a clone of the original hashmap to avoid modification by handlers
+	 * @return the hashmap [name of the field, type of the field].
+	 */
+	public String[] getInterfaces() { return (String[])m_interfaces.clone(); }
+
+	/**
+     * Manipulate the class.
+     * @param bundle    The component's m_bundle
+     * @param name      The name of the class
+     * @param cm        The component manager attached to this manipulation
+     * @return          A byte array.
+     * @throws Exception : throwed if the manipulation failed.
+     */
+    public void preProcess(String name, File outputDirectory) throws Exception {
+
+        // gets an input stream to read the bytecode of the class
+        String path = outputDirectory+"/"+name.replace('.', '/') + ".class";
+        File clazz = new File(path);
+		URL url = clazz.toURI().toURL();
+
+        //if (url == null) { throw new ClassNotFoundException(name); }
+        IpojoPluginConfiguration.getLogger().log(Level.INFO, "Manipulate the class file : " + clazz.getAbsolutePath());
+
+        InputStream is = url.openStream();
+
+        //Manipulation  ->
+        // Add the _setComponentManager method
+        // Instrument all fields
+        ClassReader cr0 = new ClassReader(is);
+        ClassWriter cw0 = new ClassWriter(true);
+        PreprocessClassAdapter preprocess = new PreprocessClassAdapter(cw0);
+        cr0.accept(preprocess, false);
+        is.close();
+
+        File file = null;
+        try {
+                file = new File(url.getFile());
+
+                
+                //file.createNewFile();
+                FileOutputStream fos = new FileOutputStream(file);
+                
+                fos.write(cw0.toByteArray());
+                
+                fos.close();
+                IpojoPluginConfiguration.getLogger().log(Level.INFO, "Put the file " + file.getAbsolutePath() + " in the jar file");
+            } catch (Exception e) { System.err.println("Problem to write the adapted class on the file system " + " [ "+ file.getAbsolutePath() +" ] " + e.getMessage()); }
+
+        m_fields = preprocess.getFields();
+        m_interfaces = new String[preprocess.getInterfaces().length];
+        for (int i = 0; i < m_interfaces.length; i++) {
+        	m_interfaces[i] = preprocess.getInterfaces()[i].replace('/', '.');
+        }
+    }
+
+
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java
new file mode 100644
index 0000000..f985bab
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java
@@ -0,0 +1,485 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.manipulation;
+
+import java.util.HashMap;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.plugin.IpojoPluginConfiguration;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+
+/**
+ * Manipulate the class.
+ * - Add a static component manager field (_cm) ok
+ * - Create getter and setter for each fields ok
+ * - Store information about field ok
+ * - Store information about implemented interfaces ok
+ * - Change GETFIELD and PUTFIELD to called the getter and setter method
+ * @author Clement Escoffier
+ *
+ */
+public class PreprocessClassAdapter extends ClassAdapter implements Opcodes {
+
+        /**
+         * The owner.
+         * m_owner : String
+         */
+        private String  m_owner;
+
+        /**
+         * Interfaces implemented by the component.
+         */
+        private String[] m_itfs = new String[0];
+
+		/**
+		 * Field hashmap [field name, type] discovered in the component class.
+		 */
+		private HashMap m_fields = new HashMap();
+
+
+        /**
+         * Constructor.
+         * @param cv : Class visitor
+         */
+        public PreprocessClassAdapter(final ClassVisitor cv) {
+            super(cv);
+        }
+
+        /** The visit method.
+         * - Insert the _cm field
+         * - Create the _initialize method
+         * - Create the _cm setter method
+         * @see org.objectweb.asm.ClassVisitor#visit(int, int, String, String, String, String[])
+         * @param version : Version
+         * @param access : Access modifier
+         * @param name : name of the visited element
+         * @param signature : singature of the visited element
+         * @param superName : superclasses (extend clause)
+         * @param interfaces : implement clause
+         */
+        public void visit(
+                final int version,
+                final int access,
+                final String name,
+                final String signature,
+                final String superName,
+                final String[] interfaces) {
+
+            m_owner = name;
+
+            // Insert _cm field
+            super.visitField(ACC_PUBLIC + ACC_STATIC, "_cm", ManipulationProperty.IPOJO_INTERNAL_DESCRIPTOR + "ComponentManager;", null, null);
+
+            // Create the _cmSetter(ComponentManager cm) method
+            createComponentManagerSetter();
+
+            //Store the interfaces :
+            m_itfs = interfaces;
+
+            super.visit(version, access, name, signature, superName, interfaces);
+        }
+
+        /** visit method method :-).
+         * @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+         * @param access : access modifier
+         * @param name : name of the method
+         * @param desc : descriptor of the method
+         * @param signature : signature of the method
+         * @param exceptions : exception launched by the method
+         * @return MethodVisitor
+         */
+        public MethodVisitor visitMethod(
+                final int access,
+                final String name,
+                final String desc,
+                final String signature,
+                final String[] exceptions) {
+            MethodVisitor mv = cv.visitMethod(access,
+                    name,
+                    desc,
+                    signature,
+                    exceptions);
+
+            if (mv == null) { return null; }
+            else { return new PreprocessCodeAdapter(mv, m_owner); }
+
+        }
+
+        /**
+         * Create the setter method for the _cm field.
+         * The generated method must be called only one time.
+         */
+        private void createComponentManagerSetter() {
+            MethodVisitor mv = super.visitMethod(ACC_PUBLIC + ACC_STATIC, "setComponentManager", "(" + ManipulationProperty.IPOJO_INTERNAL_DESCRIPTOR + "ComponentManager;)V", null, null);
+
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(PUTSTATIC, m_owner, "_cm", ManipulationProperty.IPOJO_INTERNAL_DESCRIPTOR + "ComponentManager;");
+            mv.visitInsn(RETURN);
+
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+
+        /** visit Field method.
+         * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
+         * @param access : acces modifier
+         * @param name : name of the field
+         * @param desc : description of the field
+         * @param signature : signature of the field
+         * @param value : value of the field
+         * @return FieldVisitor
+         */
+        public FieldVisitor visitField(
+                final int access,
+                final String name,
+                final String desc,
+                final String signature,
+                final Object value) {
+            if ((access & ACC_STATIC) == 0) {
+            		IpojoPluginConfiguration.getLogger().log(Level.INFO, "Manipulate the field declaration of " + name);
+                    Type type = Type.getType(desc);
+
+                    // Keep the field in the code
+                    FieldVisitor fv =  cv.visitField(access, name, desc, signature, value);
+
+                    if (type.getSort() == Type.ARRAY) {
+                    	if (type.getInternalName().startsWith("L")) {
+                    		String internalType = type.getInternalName().substring(1);
+                    		String nameType = internalType.replace('/', '.');
+                            m_fields.put(name, nameType + "[]");
+                    	}
+                    	else {
+                    		String nameType = type.getClassName().substring(0, type.getClassName().length() - 2);
+                    		m_fields.put(name, nameType);
+                    	}
+
+                    	// TODO : Getter & SETTER on array :
+                        String gDesc = "()" + desc;
+                    	createArrayGetter(name, gDesc, type);
+
+                    	// Generates setter method
+                        String sDesc = "(" + desc + ")V";
+                        createArraySetter(name, sDesc, type);
+
+                    }
+                    else {
+                    	// Store information on the fields
+                    	m_fields.put(name, type.getClassName());
+
+                    	// Generate the getter method
+                    	String gDesc = "()" + desc;
+                    	createSimpleGetter(name, gDesc, type);
+
+                    	// Generates setter method
+                        String sDesc = "(" + desc + ")V";
+                        createSimpleSetter(name, sDesc, type);
+                    }
+
+                    return fv;
+
+            }
+            return super.visitField(access, name, desc, signature, value);
+        }
+
+        private void createArraySetter(String name, String desc, Type type) {
+        	MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "_set" + name, desc, null, null);
+
+        	String internalType = desc.substring(1);
+        	internalType = internalType.substring(0, internalType.length() - 2);
+
+        	mv.visitVarInsn(ALOAD, 0);
+        	mv.visitVarInsn(ALOAD, 1);
+        	mv.visitFieldInsn(PUTFIELD, m_owner, name, internalType);
+
+        	mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+        	mv.visitLdcInsn(name);
+        	mv.visitVarInsn(ALOAD, 1);
+        	mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
+
+        	mv.visitInsn(RETURN);
+
+        	// End
+        	mv.visitMaxs(0, 0);
+            mv.visitEnd();
+		}
+
+		private void createArrayGetter(String name, String desc, Type type) {
+
+//			try {
+//            	System.out.println("Field Name : " + name);
+//            	System.out.println("Desc : " + desc);
+//            	System.out.println("ClassName : " + type.getClassName());
+//            	System.out.println("Descriptor of the type : " + type.getDescriptor());
+//            	System.out.println("Internal Name : " + type.getInternalName());
+//            } catch(Exception e) {}
+//
+
+			String methodName = "_get" + name;
+            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, methodName, desc, null, null);
+
+            String internalType = desc.substring(2);
+
+            	mv.visitVarInsn(ALOAD, 0);
+            	//mv.visitFieldInsn(GETFIELD, m_owner, name, "["+type.getInternalName()+";");
+            	mv.visitFieldInsn(GETFIELD, m_owner, name, internalType);
+            	mv.visitVarInsn(ASTORE, 1);
+
+            	mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+            	mv.visitLdcInsn(name);
+            	mv.visitVarInsn(ALOAD, 1);
+            	mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+            	mv.visitVarInsn(ASTORE, 2);
+
+            	mv.visitVarInsn(ALOAD, 2);
+            	mv.visitTypeInsn(CHECKCAST, internalType);
+            	mv.visitVarInsn(ASTORE, 3);
+
+            	Label l3a = new Label();
+            	mv.visitLabel(l3a);
+
+            	mv.visitVarInsn(ALOAD, 1);
+            	Label l4a = new Label();
+            	mv.visitJumpInsn(IFNULL, l4a);
+            	mv.visitVarInsn(ALOAD, 1);
+            	mv.visitVarInsn(ALOAD, 3);
+            	mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
+
+            	Label l5a = new Label();
+            	mv.visitJumpInsn(IFNE, l5a);
+            	mv.visitLabel(l4a);
+
+            	mv.visitVarInsn(ALOAD, 0);
+            	mv.visitVarInsn(ALOAD, 3);
+            	mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(" + internalType + ")V");
+            	mv.visitLabel(l5a);
+
+            	mv.visitVarInsn(ALOAD, 3);
+            	mv.visitInsn(ARETURN);
+
+            	//End
+            	mv.visitMaxs(0, 0);
+                mv.visitEnd();
+		}
+
+
+		/**
+         * Create the getter for service dependency.
+         * @param name : field of the dependency
+         * @param desc : description of the getter method
+         * @param type : type to return
+         */
+        private void createSimpleGetter(String name, String desc, Type type) {
+
+            String methodName = "_get" + name;
+            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, methodName, desc, null, null);
+
+            switch (type.getSort()) {
+            	case Type.BOOLEAN :
+            	case Type.CHAR :
+            	case Type.BYTE :
+            	case Type.SHORT :
+           		case Type.INT :
+           		case Type.FLOAT :
+           		case Type.LONG :
+            	case Type.DOUBLE :
+
+            		String internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];
+            		String boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];
+            		String unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];
+
+            		mv.visitVarInsn(ALOAD, 0);
+            		mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+            		mv.visitVarInsn(type.getOpcode(ISTORE), 1);
+
+            		mv.visitTypeInsn(NEW, boxingType);
+            		mv.visitInsn(DUP);
+            		mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+            		mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
+            		mv.visitVarInsn(ASTORE, 2);
+
+            		mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+            		mv.visitLdcInsn(name);
+            		mv.visitVarInsn(ALOAD, 2);
+            		mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+            		mv.visitVarInsn(ASTORE, 3);
+
+            		mv.visitVarInsn(ALOAD, 3);
+            		mv.visitTypeInsn(CHECKCAST, boxingType);
+            		mv.visitVarInsn(ASTORE, 4);
+
+            		mv.visitVarInsn(ALOAD, 4);
+            		mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);
+            		mv.visitVarInsn(type.getOpcode(ISTORE), 5);
+
+            		Label l5 = new Label();
+            		mv.visitLabel(l5);
+
+            		mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+            		mv.visitVarInsn(type.getOpcode(ILOAD), 5);
+            		Label l6 = new Label();
+            		mv.visitJumpInsn(type.getOpcode(IF_ICMPEQ), l6);
+
+            		Label l7 = new Label();
+            		mv.visitLabel(l7);
+            			mv.visitVarInsn(ALOAD, 0);
+            			mv.visitVarInsn(type.getOpcode(ILOAD), 5);
+            			mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(" + internalName + ")V");
+            		mv.visitLabel(l6);
+
+            		mv.visitVarInsn(type.getOpcode(ILOAD), 5);
+            		mv.visitInsn(type.getOpcode(IRETURN));
+            		break;
+
+            	case  Type.OBJECT :
+
+            		mv.visitVarInsn(ALOAD, 0);
+            		mv.visitFieldInsn(GETFIELD, m_owner, name, "L" + type.getInternalName() + ";");
+            		mv.visitVarInsn(ASTORE, 1);
+
+            		mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+            		mv.visitLdcInsn(name);
+            		mv.visitVarInsn(ALOAD, 1);
+            		mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+            		mv.visitVarInsn(ASTORE, 2);
+
+            		mv.visitVarInsn(ALOAD, 2);
+            		mv.visitTypeInsn(CHECKCAST, type.getInternalName());
+            		mv.visitVarInsn(ASTORE, 3);
+
+                	Label l3b = new Label();
+                	mv.visitLabel(l3b);
+
+                	mv.visitVarInsn(ALOAD, 1);
+                	Label l4b = new Label();
+                	mv.visitJumpInsn(IFNULL, l4b);
+                	mv.visitVarInsn(ALOAD, 1);
+                	mv.visitVarInsn(ALOAD, 3);
+                	mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
+
+                	Label l5b = new Label();
+                	mv.visitJumpInsn(IFNE, l5b);
+                	mv.visitLabel(l4b);
+
+                	mv.visitVarInsn(ALOAD, 0);
+                	mv.visitVarInsn(ALOAD, 3);
+                	mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(L" + type.getInternalName() + ";)V");
+                	mv.visitLabel(l5b);
+
+                	mv.visitVarInsn(ALOAD, 3);
+                	mv.visitInsn(ARETURN);
+
+            	break;
+
+                default :
+                	IpojoPluginConfiguration.getLogger().log(Level.SEVERE, "Manipulation problem in " + m_owner + " : a type is not implemented : " + type);
+                    break;
+            }
+
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+    }
+
+        /**
+         * Create the setter method for one property.
+         * The name of the method is _set+name of the field
+         * @param name : name of the field representing a property
+         * @param desc : description of the setter method
+         * @param type : type of the property
+         */
+        private void createSimpleSetter(String name, String desc, Type type) {
+            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "_set" + name, desc, null, null);
+
+            switch(type.getSort()) {
+        		case Type.BOOLEAN :
+        		case Type.CHAR :
+        		case Type.BYTE :
+        		case Type.SHORT :
+       			case Type.INT :
+       			case Type.FLOAT :
+       			case Type.LONG :
+       			case Type.DOUBLE :
+
+        		String internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];
+        		String boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];
+
+        			mv.visitVarInsn(ALOAD, 0);
+                	mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+                	mv.visitFieldInsn(PUTFIELD, m_owner, name, internalName);
+                	Label l1 = new Label();
+                	mv.visitLabel(l1);
+
+                	mv.visitTypeInsn(NEW, boxingType);
+                	mv.visitInsn(DUP);
+                	mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+                	mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
+                	mv.visitVarInsn(ASTORE, 2);
+
+                	Label l2 = new Label();
+                	mv.visitLabel(l2);
+                	mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+                	mv.visitLdcInsn(name);
+                	mv.visitVarInsn(ALOAD, 2);
+                	mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
+
+                	Label l3 = new Label();
+                	mv.visitLabel(l3);
+                	mv.visitInsn(RETURN);
+                    break;
+                case (Type.OBJECT) :
+
+                	mv.visitVarInsn(ALOAD, 0);
+                	mv.visitVarInsn(ALOAD, 1);
+                	mv.visitFieldInsn(PUTFIELD, m_owner, name, "L" + type.getInternalName() + ";");
+
+                	mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+                	mv.visitLdcInsn(name);
+                	mv.visitVarInsn(ALOAD, 1);
+                	mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
+
+                	mv.visitInsn(RETURN);
+                	break;
+                default :
+                	IpojoPluginConfiguration.getLogger().log(Level.SEVERE, "Manipulation Error : Cannot create the setter method for the field : " + name + " (" + type + ")");
+                    break;
+            }
+
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+
+        /**
+         * @return the interfaces implemented by the component class.
+         */
+        public String[] getInterfaces() {
+            return m_itfs;
+        }
+
+		/**
+		 * @return the field hashmap [field_name, type]
+		 */
+		public HashMap getFields() {
+			return m_fields;
+		}
+}
+
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessCodeAdapter.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessCodeAdapter.java
new file mode 100644
index 0000000..16bc1ee
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessCodeAdapter.java
@@ -0,0 +1,80 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.manipulation;
+
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.plugin.IpojoPluginConfiguration;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+
+/**
+ * Date : 29 janv. 2006
+ * @author clément
+ *
+ */
+public class PreprocessCodeAdapter extends MethodAdapter implements Opcodes {
+
+    /** The owner class of the field.
+     * m_owner : String
+     */
+    private String m_owner;
+
+    /** PropertyCodeAdapter constructor.
+     * A new FiledCodeAdapter should be create for each method visit.
+     * @param mv MethodVisitor
+     * @param owner Name of the class
+     */
+    public PreprocessCodeAdapter(final MethodVisitor mv, final String owner) {
+        super(mv);
+        m_owner = owner;
+    }
+
+
+    /** Visit Method for Filed instance (GETFIELD).
+     * @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int, String, String, String)
+     * @param opcode : visited operation code
+     * @param owner : owner of the field
+     * @param name : name of the field
+     * @param desc : decriptor of the field
+     */
+    public void visitFieldInsn(
+            final int opcode,
+            final String owner,
+            final String name,
+            final String desc) {
+        if (owner.equals(m_owner)) {
+            if (opcode == GETFIELD) {
+            		IpojoPluginConfiguration.getLogger().log(Level.INFO, "Manipulate a GETFIELD on : " + name);
+                    String gDesc = "()" + desc;
+                    visitMethodInsn(INVOKEVIRTUAL, owner, "_get" + name, gDesc);
+                    return;
+            } else
+            	if (opcode == PUTFIELD) {
+            		// replaces PUTFIELD f by INVOKESPECIAL _setf
+            		IpojoPluginConfiguration.getLogger().log(Level.INFO, "Manipulate a PUTFIELD on : " + name);
+            		String sDesc = "(" + desc + ")V";
+            		visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);
+            		return;
+            	}
+        }
+        super.visitFieldInsn(opcode, owner, name, desc);
+    }
+}
+
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
new file mode 100644
index 0000000..861cf75
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
@@ -0,0 +1,181 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.parser;
+
+import java.util.Dictionary;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.plugin.IpojoPluginConfiguration;
+
+/**
+ * Manifest Metadata parser.
+ * Read a manifest file and construct metadata
+ * @author Clement Escoffier
+ */
+public class ManifestMetadataParser {
+
+	/**
+	 * Manifest Headers.
+	 */
+	private Dictionary m_headers;
+
+	/**
+	 * Element list.
+	 */
+	private Element[] m_elements = new Element[0];
+
+    /**
+     * @return the component metadata.
+     * @throws ParseException when a parsing error occurs
+     */
+    public Element[] getComponentsMetadata() throws ParseException {
+    	return m_elements[0].getElements("Component");
+    }
+
+    private void addElement(Element elem) {
+    	for (int i = 0; (m_elements != null) && (i < m_elements.length); i++) {
+            if (m_elements[i] == elem) { return; }
+        }
+
+        if (m_elements != null) {
+            Element[] newElementsList = new Element[m_elements.length + 1];
+            System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
+            newElementsList[m_elements.length] = elem;
+            m_elements = newElementsList;
+        }
+        else { m_elements = new Element[] {elem}; }
+	}
+
+    private Element removeLastElement() {
+		int idx = -1;
+		idx = m_elements.length - 1;
+		Element last = m_elements[idx];
+        if (idx >= 0) {
+            if ((m_elements.length - 1) == 0) {
+            	// It is the last element of the list;
+            	m_elements = new Element[0];
+            	}
+            else {
+            	// Remove the last element of the list :
+                Element[] newElementsList = new Element[m_elements.length - 1];
+                System.arraycopy(m_elements, 0, newElementsList, 0, idx);
+                m_elements = newElementsList;
+            }
+        }
+        return last;
+	}
+
+	/**
+	 * Parse the given dictionnary and create the components manager.
+	 * @param dict : the given headers of the manifest file
+	 * @throws ParseException : if any error occurs
+	 */
+	public void parse(Dictionary dict) throws ParseException {
+		m_headers = dict;
+		String componentClassesStr = (String)m_headers.get("iPOJO-Components");
+		System.out.println("Parse : " + componentClassesStr);
+		parseElements(componentClassesStr.trim());
+
+	}
+	
+	/**
+	 * PArse the metadata from the string given in argument.
+	 * @param metadata : the metadata
+	 * @throws ParseException when a parse error occurs
+	 */
+	public void parse(String metadata) throws ParseException {
+		parseElements(metadata);
+	}
+
+	private void parseElements(String s) {
+		//Add the ipojo element inside the element list
+		addElement(new Element("iPOJO", ""));
+		char[] string = s.toCharArray();
+
+		for (int i = 0; i < string.length; i++) {
+			char c = string[i];
+			System.out.println("Analyse : " + c);
+			switch(c) {
+
+			case '$' :
+				String attName = "";
+				String attValue = "";
+				String attNs = ""; 
+				i++;
+				c = string[i];
+				while (c != '=') {
+					if(c == ':') {
+						attNs = attName;
+						attName= "";
+					} else { attName = attName + c; } 
+					i = i + 1;
+					c = string[i];
+				}
+				i++; // skip =
+				c = string[i];
+				while (c != ' ') {
+					attValue = attValue + c;
+					i++;
+					c = string[i];
+				}
+				Attribute att = new Attribute(attName, attNs ,attValue);
+				IpojoPluginConfiguration.getLogger().log(Level.INFO, "Detect a new  attribute : '" + "[" + attNs + "]" + attName + "' = '" + attValue + "'");
+				m_elements[m_elements.length - 1].addAttribute(att);
+				break;
+
+			case '}' :
+				Element lastElement = removeLastElement();
+				IpojoPluginConfiguration.getLogger().log(Level.INFO, "End of the element : " + lastElement.getName());
+				if (m_elements.length != 0) {
+					Element newQueue = m_elements[m_elements.length - 1];
+					newQueue.addElement(lastElement);
+				}
+				else {
+					addElement(lastElement);
+				}
+				break;
+			case ' ' : break; // do nothing;
+			default :
+					String name = "";
+					String ns = "";
+					c = string[i];
+					while (c != ' ') {
+						if(c == ':') {
+							ns = name;
+							name = "";
+							i++;
+						} 
+						else {
+							name = name + c;
+							i++;
+							c = string[i];
+						}
+					}
+					// Skip spaces
+					while (string[i] == ' ') { i = i + 1; }
+					i = i + 1; // skip {
+				    Element elem = new Element(name, ns);
+					addElement(elem);
+					IpojoPluginConfiguration.getLogger().log(Level.INFO, "Start an new element : " + name);
+				break;
+			}
+			}
+		}
+
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/ParseException.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/ParseException.java
new file mode 100644
index 0000000..4cf61b8
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/ParseException.java
@@ -0,0 +1,38 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.parser;
+
+/**
+ * Exceptions thrown by parsers.
+ * @author Clement Escoffier
+ */
+public class ParseException extends Exception {
+
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Parsing error.
+     * @param msg : the error emssage.
+     */
+    public ParseException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/XMLMetadataParser.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/XMLMetadataParser.java
new file mode 100644
index 0000000..7ce57f4
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/XMLMetadataParser.java
@@ -0,0 +1,193 @@
+/**
+ * 
+ */
+package org.apache.felix.ipojo.parser;
+
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.plugin.IpojoPluginConfiguration;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * @author escoffie
+ *
+ */
+public class XMLMetadataParser implements ContentHandler {
+	
+	
+	/**
+	 * Element of the metadata.
+	 */
+	private Element[] m_elements = new Element[0];
+
+    /**
+     * @return a components metadata
+     * @throws ParseException when an error occurs in the xml parsing
+     */
+    public Element[] getComponentsMetadata() throws ParseException {
+    	return m_elements[0].getElements("Component");
+    }
+    
+    
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+	 */
+	public void characters(char[] ch, int start, int length)
+			throws SAXException {
+		// NOTHING TO DO
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#endDocument()
+	 */
+	public void endDocument() throws SAXException {
+		IpojoPluginConfiguration.getLogger().log(Level.INFO, "End of the XML parsing, " + m_elements.length + " primary elements found");
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void endElement(String namespaceURI, String localName, String qName)
+			throws SAXException {
+	   	// Get the last element of the list
+        Element lastElement = removeLastElement();
+
+        // Check if the name is consitent with the name of this end tag
+        if (!lastElement.getName().equalsIgnoreCase(qName) && !lastElement.getNameSpace().equals(namespaceURI)) {
+        	IpojoPluginConfiguration.getLogger().log(Level.SEVERE, "Parse error when ending an element : " + qName + " [" + namespaceURI + "]");
+        	throw new SAXException("Parse error when ending an element : " + qName + " [" + namespaceURI + "]");
+        }
+
+        // The name is consitent
+        // Add this element last element with if it is not the root
+        if (m_elements.length != 0) {
+        	Element newQueue = m_elements[m_elements.length - 1];
+        	newQueue.addElement(lastElement);
+        }
+        else {
+        	// It is the last element
+        	addElement(lastElement);
+        }
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
+	 */
+	public void endPrefixMapping(String prefix) throws SAXException {
+		//NOTHING TO DO
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+	 */
+	public void ignorableWhitespace(char[] ch, int start, int length)
+			throws SAXException {
+		// NOTHING TO DO
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
+	 */
+	public void processingInstruction(String target, String data)
+			throws SAXException {
+		// DO NOTHING
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
+	 */
+	public void setDocumentLocator(Locator locator) {
+		// NOTHING TO DO
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
+	 */
+	public void skippedEntity(String name) throws SAXException {
+		// NOTHING TO DO
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#startDocument()
+	 */
+	public void startDocument() throws SAXException {
+		IpojoPluginConfiguration.getLogger().log(Level.INFO, "Start of the XML parsing");
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+	 */
+	public void startElement(String namespaceURI, String localName,
+			String qName, Attributes atts) throws SAXException {
+		IpojoPluginConfiguration.getLogger().log(Level.INFO, "An XML tag was openend : " + localName + " [" + namespaceURI + "]");
+
+        Element elem = new Element(localName, namespaceURI);     
+        
+        for (int i = 0; i < atts.getLength(); i++) {
+        	String name = (String)atts.getLocalName(i);
+        	String ns = (String) atts.getURI(i);
+        	String value = (String)atts.getValue(i);
+        	Attribute att = new Attribute(name, ns, value);
+        	elem.addAttribute(att);
+        }
+
+        addElement(elem);
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
+	 */
+	public void startPrefixMapping(String prefix, String uri)
+			throws SAXException {
+		// NOTHING TO DO
+
+	}
+	
+	private void addElement(Element elem) {
+    	for (int i = 0; (m_elements != null) && (i < m_elements.length); i++) {
+            if (m_elements[i] == elem) { return; }
+        }
+
+        if (m_elements != null) {
+            Element[] newElementsList = new Element[m_elements.length + 1];
+            System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
+            newElementsList[m_elements.length] = elem;
+            m_elements = newElementsList;
+        }
+        else { m_elements = new Element[] {elem}; }
+	}
+	
+	private Element removeLastElement() {
+		int idx = -1;
+		idx = m_elements.length - 1;
+		Element last = m_elements[idx];
+        if (idx >= 0) {
+            if ((m_elements.length - 1) == 0) {
+            	// It is the last element of the list;
+            	m_elements = new Element[0];
+            	}
+            else {
+            	// Remove the last element of the list :
+                Element[] newElementsList = new Element[m_elements.length - 1];
+                System.arraycopy(m_elements, 0, newElementsList, 0, idx);
+                m_elements = newElementsList;
+            }
+        }
+        return last;
+	}
+
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Clazz.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Clazz.java
new file mode 100644
index 0000000..da59cff
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Clazz.java
@@ -0,0 +1,190 @@
+package org.apache.felix.ipojo.plugin;
+
+import java.io.*;
+import java.util.*;
+
+public class Clazz {
+	static byte	SkipTable[]	= {0, // 0 non existent
+		-1, // 1 CONSTANT_utf8 UTF 8, handled in
+		// method
+		-1, // 2
+		4, // 3 CONSTANT_Integer
+		4, // 4 CONSTANT_Float
+		8, // 5 CONSTANT_Long (index +=2!)
+		8, // 6 CONSTANT_Double (index +=2!)
+		-1, // 7 CONSTANT_Class
+		2, // 8 CONSTANT_String
+		4, // 9 CONSTANT_FieldRef
+		4, // 10 CONSTANT_MethodRef
+		4, // 11 CONSTANT_InterfaceMethodRef
+		4, // 12 CONSTANT_NameAndType
+						};
+
+	Set			imports = new HashSet();
+	String		path;
+	Jar			jar;
+	
+	public Clazz(Jar jar, String path, InputStream in) throws IOException {
+		this.path = path;
+		this.jar = jar;
+		DataInputStream din = new DataInputStream(in);
+		parseClassFile(din);
+	}
+
+
+	void parseClassFile(DataInputStream in)
+			throws IOException {
+		Set classes = new HashSet();
+		Set descriptors = new HashSet();
+		Hashtable pool = new Hashtable();
+		try {
+			int magic = in.readInt();
+			if (magic != 0xCAFEBABE)
+				throw new IOException(
+						"Not a valid class file (no CAFEBABE header)");
+			in.readShort(); // minor version
+			in.readShort(); // major version
+			int count = in.readUnsignedShort();
+			process: for (int i = 1; i < count; i++) {
+				byte tag = in.readByte();
+				switch (tag) {
+					case 0 :
+						break process;
+					case 1 :
+						// CONSTANT_Utf8
+						String name = in.readUTF();
+						pool.put(new Integer(i), name);
+						break;
+					// A Class constant is just a short reference in
+					// the constant pool
+					case 7 :
+						// CONSTANT_Class
+						Integer index = new Integer(in.readShort());
+						classes.add(index);
+						break;
+					// For some insane optimization reason are
+					// the long and the double two entries in the
+					// constant pool. See 4.4.5
+					case 5 :
+						// CONSTANT_Long
+					case 6 :
+						// CONSTANT_Double
+						in.skipBytes(8);
+						i++;
+						break;
+
+					// Interface Method Ref
+					case 12 :
+						in.readShort(); // Name index
+						int descriptorIndex = in.readShort();
+						descriptors.add(new Integer(descriptorIndex));
+						break;
+
+					// We get the skip count for each record type
+					// from the SkipTable. This will also automatically
+					// abort when
+					default :
+						if (tag == 2)
+							throw new IOException("Invalid tag " + tag);
+						in.skipBytes(SkipTable[tag]);
+						break;
+				}
+			}
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+			return;
+		}
+		//
+		// Now iterate over all classes we found and
+		// parse those as well. We skip duplicates
+		//
+
+		for (Iterator e = classes.iterator(); e.hasNext();) {
+			Integer n = (Integer) e.next();
+			String next = (String) pool.get(n);
+			if (next != null) {
+				String normalized = normalize(next);
+				if (normalized != null) {
+                    // For purposes of trying to guess the activator class, we assume
+                    // that any class that references the BundleActivator interface
+                    // must be a BundleActivator implementation.
+					if ( normalized.startsWith("org/osgi/framework/BundleActivator")) {
+						String cname = path.replace('/', '.');
+						cname = cname.substring(0,cname.length()-".class" .length());
+						jar.addActivator(cname);
+					}
+					String pack = getPackage(normalized);
+					if (!pack.startsWith("java."))
+						imports.add(pack);
+				}
+			}
+			else
+				throw new IllegalArgumentException("Invalid class, parent=");
+		}
+		for (Iterator e = descriptors.iterator(); e.hasNext();) {
+			Integer n = (Integer) e.next();
+			String prototype = (String) pool.get(n);
+			if (prototype != null)
+				parseDescriptor(prototype);
+		}
+	}
+
+	void parseDescriptor(String prototype) {
+		addReference(prototype);
+		StringTokenizer st = new StringTokenizer(prototype, "(;)", true);
+		while (st.hasMoreTokens()) {
+			if (st.nextToken().equals("(")) {
+				String token = st.nextToken();
+				while (!token.equals(")")) {
+					addReference(token);
+					token = st.nextToken();
+				}
+				token = st.nextToken();
+				addReference(token);
+			}
+		}
+	}
+
+	private void addReference(String token) {
+		if (token.startsWith("L")) {
+			String clazz = normalize(token.substring(1));
+			if (clazz.startsWith("java/"))
+				return;
+			String pack = getPackage(clazz);
+			imports.add(pack);
+		}
+	}
+
+	static String normalize(String s) {
+		if (s.startsWith("[L"))
+			return normalize(s.substring(2));
+		if (s.startsWith("["))
+			if (s.length() == 2)
+				return null;
+			else
+				return normalize(s.substring(1));
+		if (s.endsWith(";"))
+			return normalize(s.substring(0, s.length() - 1));
+		return s + ".class";
+	}
+
+	static String getPackage(String clazz) {
+		int n = clazz.lastIndexOf('/');
+		if (n < 0)
+			return ".";
+		return clazz.substring(0, n).replace('/', '.');
+	}
+
+
+	public Collection getReferred() {
+		return imports;
+	}
+
+
+	public Object getPath() {
+		return path;
+	}
+
+
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/IpojoPluginConfiguration.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/IpojoPluginConfiguration.java
new file mode 100644
index 0000000..eefb9c3
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/IpojoPluginConfiguration.java
@@ -0,0 +1,21 @@
+package org.apache.felix.ipojo.plugin;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class IpojoPluginConfiguration {
+
+	private static Logger logger;
+	
+	public static Level logLevel = Level.WARNING; 
+	
+	public static Logger getLogger() {
+		if (logger == null) {
+			String name = "org.apache.felix.ipojo.tools.plugin";
+			logger = Logger.getLogger(name);
+			logger.setLevel(logLevel);
+		}
+		return logger;
+	}
+	
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Jar.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Jar.java
new file mode 100644
index 0000000..b901ce3
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/Jar.java
@@ -0,0 +1,176 @@
+package org.apache.felix.ipojo.plugin;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.zip.*;
+
+public class Jar {
+	Map			resources	= new TreeMap();
+	Map			imports		= new HashMap();
+	Map			exports		= new HashMap();
+	Manifest	manifest;
+	boolean		manifestFirst;
+	String		name;
+	Jar			parent;
+	List		activators	= new ArrayList();
+
+	public Jar(Jar parent, String name, InputStream in) throws IOException {
+		this.name = name;
+		this.parent = parent;
+		ZipInputStream jar = new ZipInputStream(in);
+		ZipEntry entry = jar.getNextEntry();
+		boolean first = true;
+		while (entry != null) {
+			String path = entry.getName();
+
+			if (path.endsWith(".class")) {
+				Clazz clazz = new Clazz(this, path, jar);
+				resources.put(path, clazz);
+			}
+			else if (path.endsWith(".jar")) {
+				Jar pool = new Jar(this, path, jar);
+				resources.put(path, pool);
+			}
+			else if (path.endsWith("/packageinfo")
+					&& !path.startsWith("OSGI-OPT")) {
+				String version = parsePackageInfo(jar, exports);
+				resources.put(path, version);
+			}
+			else if (path.equals("META-INF/MANIFEST.MF")) {
+				manifestFirst = first;
+				manifest = new Manifest(jar);
+			}
+			else
+				resources.put(path, null);
+
+			entry = jar.getNextEntry();
+			if (!path.endsWith("/"))
+				first = false;
+		}
+	}
+
+	public Jar(Jar parent, String name, File rootDir) throws IOException {
+		this.name = name;
+		this.parent = parent;
+		traverse(rootDir.getAbsolutePath().length(), rootDir, rootDir.list());
+	}
+
+	void traverse(int root, File dir, String list[]) throws IOException {
+		for (int i = 0; i < list.length; i++) {
+			File sub = new File(dir, list[i]);
+			if (sub.isDirectory())
+				traverse(root, sub, sub.list());
+			else {
+				String path = sub.getAbsolutePath().substring(root + 1)
+						.replace(File.separatorChar, '/');
+				FileInputStream in = new FileInputStream(sub);
+
+				if (path.endsWith(".class")) {
+					Clazz clazz = new Clazz(this, path, in);
+					resources.put(path, clazz);
+				}
+				else if (path.endsWith(".jar")) {
+					Jar pool = new Jar(this, path, in);
+					resources.put(path, pool);
+				}
+				else if (path.endsWith("/packageinfo")
+						&& !path.startsWith("OSGI-OPT")) {
+					String version = parsePackageInfo(in, exports);
+					resources.put(path, version);
+				}
+				else if (path.endsWith("META-INF/MANIFEST.MF")) {
+					manifest = new Manifest(in);
+				}
+				else
+					resources.put(path, null);
+			}
+		}
+	}
+
+	private static String parsePackageInfo(InputStream jar, Map exports)
+			throws IOException {
+		try {
+			byte[] buf = collect(jar, 0);
+			String line = new String(buf);
+			StringTokenizer qt = new StringTokenizer(line, " \r\n\t");
+			if (qt.hasMoreElements()) {
+				qt.nextToken();
+				if (qt.hasMoreElements()) {
+					String version = qt.nextToken();
+					return version;
+				}
+			}
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * Convenience method to turn an inputstream into a byte array. The method
+	 * uses a recursive algorithm to minimize memory usage.
+	 * 
+	 * @param in stream with data
+	 * @param offset where we are in the stream
+	 * @returns byte array filled with data
+	 */
+	private static byte[] collect(InputStream in, int offset)
+			throws IOException {
+		byte[] result;
+		byte[] buffer = new byte[10000];
+		int size = in.read(buffer);
+		if (size <= 0)
+			return new byte[offset];
+		else
+			result = collect(in, offset + size);
+		System.arraycopy(buffer, 0, result, offset, size);
+		return result;
+	}
+
+	public Manifest getManifest() {
+		return manifest;
+	}
+
+	public Object getEntry(String resource) {
+		return resources.get(resource);
+	}
+
+	public boolean exists(String jarOrDir) {
+		return resources.keySet().contains(jarOrDir);
+	}
+
+	public Set getEntryPaths(String prefix) {
+		Set result = new TreeSet();
+		for (Iterator i = resources.keySet().iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			if (path.startsWith(prefix))
+				result.add(path);
+		}
+		return result;
+	}
+
+	String getName() {
+		return name;
+	}
+
+	public String toString() {
+		return getName();
+	}
+
+	public void addActivator(String path) {
+		if (parent != null)
+			parent.addActivator(path);
+		else {
+			activators.add(path);
+		}
+
+	}
+
+    public boolean containsActivator(String path) {
+        if (parent != null)
+            return parent.containsActivator(path);
+        return activators.contains(path);
+    }
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
new file mode 100644
index 0000000..95cc5b4
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
@@ -0,0 +1,869 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.plugin;
+
+//import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+//import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.felix.ipojo.manipulation.Manipulator;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+//import org.apache.felix.ipojo.parser.KXml2SAXParser;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+//import org.apache.felix.ipojo.parser.XMLGenericMetadataParser;
+import org.apache.felix.ipojo.parser.XMLMetadataParser;
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+import org.codehaus.plexus.util.FileUtils;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+//import org.xmlpull.v1.XmlPullParserException;
+
+/**
+ * Package an OSGi jar "bundle."
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Apache Felix Project</a>
+ * @version $Rev$, $Date$
+ * @goal ipojo-bundle
+ * @phase package
+ * @requiresDependencyResolution runtime
+ * @description build an OSGi bundle jar
+ */
+public class OsgiJarMojo extends AbstractMojo {
+	private static final String[]		EMPTY_STRING_ARRAY		= {};
+
+	int									bundleManifestVersion	= 1;
+
+	/**
+	 * The Maven project.
+	 * 
+	 * @parameter expression="${project}"
+	 * @required
+	 * @readonly
+	 */
+	private MavenProject				project;
+
+	/**
+	 * The directory for the generated JAR.
+	 * 
+	 * @parameter expression="${project.build.directory}"
+	 * @required
+	 */
+	private String						buildDirectory;
+
+	/**
+	 * The directory containing generated classes.
+	 * 
+	 * @parameter expression="${project.build.outputDirectory}"
+	 * @required
+	 * @readonly
+	 */
+	private File						outputDirectory;
+
+	/**
+	 * The name of the generated JAR file.
+	 * 
+	 * @parameter alias="jarName" expression="${project.build.finalName}"
+	 * @required
+	 */
+	private String						jarName;
+
+	/**
+	 * The Jar archiver.
+	 * 
+	 * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
+	 * @required
+	 */
+	private JarArchiver					jarArchiver;
+
+	/**
+	 * The maven archive configuration to use.
+	 */
+	private MavenArchiveConfiguration	archiveConfig			= new MavenArchiveConfiguration();
+
+	/**
+	 * The comma separated list of tokens to include in the JAR. Default is
+	 * '**'.
+	 * 
+	 * @parameter alias="includes"
+	 */
+	private String						jarSourceIncludes		= "**";
+
+	/**
+	 * The comma separated list of tokens to exclude from the JAR.
+	 * 
+	 * @parameter alias="excludes"
+	 */
+	private String						jarSourceExcludes;
+
+	/**
+	 * @parameter
+	 */
+	private String						manifestFile;
+
+	/**
+	 * @parameter expression="${org.apache.felix.ipojo.tools.maven.plugin.OsgiManifest}"
+	 */
+	private OsgiManifest				osgiManifest;
+	
+	private String[][] namespaces; 
+
+	/**
+	 * Execute this Mojo
+	 * 
+	 * @throws MojoExecutionException
+	 */
+	public void execute() throws MojoExecutionException {
+		File jarFile = new File(buildDirectory, jarName + ".jar");
+
+		try {
+			performPackaging(jarFile);
+		}
+		catch (Exception e) {
+			throw new MojoExecutionException("Error assembling JAR bundle", e);
+		}
+	}
+
+	/**
+	 * Generates the JAR bundle file.
+	 * 
+	 * @param jarFile the target JAR file
+	 * @throws IOException
+	 * @throws ArchiverException
+	 * @throws ManifestException
+	 * @throws DependencyResolutionRequiredException
+	 */
+	private void performPackaging(File jarFile) throws IOException,
+			ArchiverException, ManifestException,
+			DependencyResolutionRequiredException, MojoExecutionException {
+
+		verifyDeclaredBundleManifestVersion();
+
+		getLog().info("Generating JAR bundle " + jarFile.getAbsolutePath());
+
+		MavenArchiver archiver = new MavenArchiver();
+
+		archiver.setArchiver(jarArchiver);
+		archiver.setOutputFile(jarFile);
+
+		addManifestFile();
+		addManifestEntries();
+
+		// Add the JARs that were specified in the POM
+		// as "not" provided
+		addEmbeddedJars();
+		addBundleVersion();
+		
+		// Insert iPOJO Manipulation
+		iPojoManipulation();
+
+		jarArchiver.addDirectory(outputDirectory, getIncludes(), getExcludes());
+
+		// Parse the output directory as if it was a JAR file.
+		// This creates special entries for classes, packageinfo
+		// and embedded JAR files (which are parsed as well).
+		Jar mainJar = new Jar(null, jarName, outputDirectory);
+
+		// Calculate the Bundle Classpath from the embedded
+		// JAR files. We hardcode the bcp as ., <embedded jars>
+		// TODO we add all the found JARs to the Bcp, maybe we
+		// should look if they are needed by traversing the imports.
+		List bundleClassPath = getBundleClassPath(mainJar);
+		bundleClassPath.add(0, ".");
+		createBundleClasspathHeader(bundleClassPath);
+
+		// Calculate the exports (contained) and imports (referred)
+		// The bundleClassPath contains the JARs in the right order
+		Set contained = new HashSet(); // package name
+		Set referred = new HashSet(); // package name
+		Map uses = new HashMap(); // package name => Set of package name
+
+		// Iterate over the bundle class path and calculate the contained
+		// and referred packages as well as the uses.
+		for (Iterator i = bundleClassPath.iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			Jar jar = path.equals(".") ? mainJar : (Jar) mainJar.resources
+					.get(path);
+			analyzeJar(jar, contained, referred, uses);
+		}
+
+		referred.removeAll(contained);
+
+		Map exports = parseHeader(osgiManifest.getExportPackage());
+		Map imports = parseHeader(osgiManifest.getImportPackage());
+		Map dynamicImports = parseHeader(osgiManifest.getDynamicImportPackage());
+
+		if (dynamicImports != null) {
+			// Remove any dynamic imports from the referred set.
+			referred = new HashSet(referred);
+			referred.removeAll(dynamicImports.keySet());
+		}
+
+		if (exports != null) {
+			verifyDeclaredExports(exports, contained);
+			createExportHeader(exports, uses);
+		}
+
+		// If the POM file contains an import declaration,
+		// we verify its validity. Otherwise, we generate the
+		// import package header from the referred. Exports
+		// are added to automatically imports for R4 bundles.
+		if (imports == null) {
+			createImportHeader(referred, exports == null ? new HashSet()
+					: exports.keySet());
+		}
+		else {
+			verifyDeclaredImports(referred, imports);
+		}
+
+		//verifyBundleActivator(mainJar); // Replace it by setBundleActivator
+		
+		
+		archiver.createArchive(project, archiveConfig);
+		project.getArtifact().setFile(jarFile);
+	}
+	
+	private Element[] parseXMLMetadata(String path) throws MojoExecutionException {
+		File metadata = new File(outputDirectory+path);
+		URL url;
+		Element[] components = null;
+		try {
+			url = metadata.toURI().toURL();
+			if (url == null) { 
+				getLog().error("No metadata at : " + outputDirectory+path);
+				throw new MojoExecutionException("[iPOJO] No metadata at : " + outputDirectory+path); 
+			}
+			
+			InputStream stream = url.openStream();
+
+//	        //Open the file and parse :
+//			BufferedReader in = new BufferedReader(new InputStreamReader(stream));
+//		    XMLGenericMetadataParser handler = new XMLGenericMetadataParser();
+//		    KXml2SAXParser parser;
+//			parser = new KXml2SAXParser(in);
+//			parser.parseXML(handler);
+//		    stream.close();
+			
+			XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+			XMLMetadataParser handler = new XMLMetadataParser();
+			parser.setContentHandler(handler);
+			InputSource is = new InputSource(stream);
+			parser.parse(is);
+		    
+		    components = handler.getComponentsMetadata();
+
+		    
+		} catch (MalformedURLException e) {
+			getLog().error("Malformed URL for " + outputDirectory+path+ "("+e.getMessage()+")");
+			throw new MojoExecutionException("[iPOJO] Malformed URL for " + outputDirectory+path);
+		} catch (IOException e) { 
+        	getLog().error("Cannot open the file : " + outputDirectory+path + "("+e.getMessage()+")");
+			throw new MojoExecutionException("[iPOJO] Cannot open the file : " + outputDirectory+path);
+//        } catch (XmlPullParserException e) {
+//        	getLog().error("Error when  parsing the XML file " + outputDirectory+path+ "("+e.getMessage()+")");
+//			throw new MojoExecutionException("[iPOJO] Error when  parsing the XML file " + outputDirectory+path);
+		} catch (Exception e) {
+			getLog().error("Parsing Error when parsing the XML file " + outputDirectory+path+ "("+e.getMessage()+")");
+			throw new MojoExecutionException("[iPOJO] Parsing Error when parsing the XML file " + outputDirectory+path);
+		}
+		
+		if(components == null || components.length == 0) {
+			getLog().error("No component in " + outputDirectory+path);
+			throw new MojoExecutionException("[iPOJO] No component in " + outputDirectory+path);
+		}
+		
+		return components;
+	}
+	
+	private Element[] parseManifestMetadata(String metadata) throws MojoExecutionException {
+		Element[] components = null;
+		ManifestMetadataParser parser = new ManifestMetadataParser();
+    	try {
+			parser.parse(metadata);
+			components = parser.getComponentsMetadata();
+		} catch (ParseException e) {
+			getLog().error("Parsing Error when parsing the Manifest metadata " +  metadata + "("+e.getMessage()+")");
+			throw new MojoExecutionException("[iPOJO] Parsing Error when parsing the Manifest metadata " +  metadata);
+			
+		}
+    	
+		if(components == null || components.length == 0) {
+			getLog().error("No component in " + metadata);
+			throw new MojoExecutionException("[iPOJO] No component in " + metadata);
+		}
+        
+        return components;
+	}
+	
+	private void iPojoManipulation() throws MojoExecutionException {
+		//Try to read the content of a file of the ouptut directory
+		getLog().info("iPOJO Manipulation ...");
+		
+		Element[] components = null;
+		
+		// Get the metadata.xml location 
+		String path = (String) osgiManifest.getEntries().get("iPOJO-Metadata");
+		
+		if(path != null) {
+			if(!path.startsWith("/")) { path = "/" + path; }
+			components = parseXMLMetadata(path);
+		} else {
+			String meta_ = (String) osgiManifest.getEntries().get("iPOJO-Components");
+			if(meta_ != null) {
+				components = parseManifestMetadata(meta_);
+			} else {
+				getLog().error("Neither iPOJO-Metadata nor iPOJO-Components are in the manifest, please in the osgi-bundle packaging instead og ipojo-bundle");
+				throw new MojoExecutionException("[iPOJO] Neither iPOJO-Metadata nor iPOJO-Components are in the manifest");
+			}
+				
+		}
+		
+			
+		Manipulator manipulator = new Manipulator();
+		String[] metadata = new String[components.length];
+		String meta = "";
+		if(namespaces == null) { namespaces = new String[components.length][]; }
+        for(int i = 0; i < components.length; i++) {
+        	getLog().info("Component Class Name : " + components[i].getAttribute("className"));
+        	namespaces[i] = components[i].getNamespaces();
+        	try {
+				manipulator.preProcess(components[i].getAttribute("className"), outputDirectory);
+			} catch (Exception e) {
+				getLog().error("Manipulation error in the class : " + components[i].getAttribute("className") + "("+e.getMessage()+")");
+				throw new MojoExecutionException("[iPOJO] Manipulation error in the class : " + components[i].getAttribute("className"));
+			}
+        	
+        	getLog().info("Add manipulation metadata for : " + components[i].getAttribute("className"));
+        	// Insert information to metadata
+        	Element elem = new Element("Manipulation", "");
+        	for(int j = 0; j < manipulator.getInterfaces().length; j++) {
+        		// Create an interface element for each implemented interface
+        		Element itf = new Element("Interface", "");
+        		Attribute att =new Attribute("name", manipulator.getInterfaces()[j]);
+        		itf.addAttribute(att);
+        		elem.addElement(itf);
+        	}
+
+        	for(Iterator it = manipulator.getFields().keySet().iterator(); it.hasNext(); ) {
+        		Element field = new Element("Field", "");
+        		String name = (String) it.next();
+        		String type = (String) manipulator.getFields().get(name);
+        		Attribute attName =new Attribute("name", name);
+        		Attribute attType =new Attribute("type", type);
+        		field.addAttribute(attName);
+        		field.addAttribute(attType);
+        		elem.addElement(field);
+        	}
+
+        	components[i].addElement(elem);
+        	
+        	// Transform the metadate to manifest metadata
+        	metadata[i] = buildManifestMetadata(components[i], "");
+        	meta = meta + metadata[i];
+        }
+        
+        getLog().info("Metadata of the bundles : " + meta);
+	    archiveConfig.addManifestEntry("iPOJO-Components", meta);
+	        
+	    getLog().info("Set the bundle activator");
+	    setBundleActivator();
+			
+	    getLog().info("iPOJO Manipulation ... SUCCESS");
+		
+	}
+
+	private String buildManifestMetadata(Element element, String actual) {
+		String result="";
+		if(element.getNameSpace().equals("")) { result = actual + element.getName() + " { "; }
+		else { result = actual + element.getNameSpace()+":"+element.getName() + " { ";	}
+		
+		for(int i = 0; i < element.getAttributes().length; i++) {
+			if(element.getAttributes()[i].getNameSpace().equals("")) { 
+				result = result + "$" + element.getAttributes()[i].getName() + "="+element.getAttributes()[i].getValue() + " ";
+			}
+			else {
+				result = result + "$" + element.getAttributes()[i].getNameSpace()+ ":" + element.getAttributes()[i].getName() + "="+element.getAttributes()[i].getValue() + " ";
+			}
+		}
+		for(int i = 0; i < element.getElements().length; i++) {
+			result = buildManifestMetadata(element.getElements()[i], result);
+		}
+		return result +"}";
+	}
+
+	private void setBundleActivator() throws MojoExecutionException {
+		archiveConfig.addManifestEntry("Bundle-Activator", "org.apache.felix.ipojo.Activator");		
+	}
+
+//	private void verifyBundleActivator(Jar mainJar) {
+//		String ba = osgiManifest.getBundleActivator();
+//		if (ba == null || ba.trim().length() == 0) {
+//			switch ( mainJar.activators.size() ) {
+//				case 0: break;
+//				case 1: archiveConfig.addManifestEntry("Bundle-Activator", mainJar.activators.get(0));
+//				break;
+//				default:
+//					getLog().info("[OSGi] No Bundle-Activator specified and multiple found" );
+//				break;
+//			}
+//		}
+//		else {
+//			if( ! mainJar.activators.contains(ba))
+//				getLog().warn("[OSGi] UNABLE TO VERIFY BUNDLE ACTIVATOR: " + ba);
+//		}
+//	}
+
+	private void createBundleClasspathHeader(List bundleClassPath) {
+		StringBuffer sb = new StringBuffer();
+		String del = ".,";
+		for (Iterator i = bundleClassPath.iterator(); i.hasNext();) {
+			sb.append(del);
+			sb.append(i.next());
+			del = ",";
+		}
+		if (sb.length() > 0)
+			archiveConfig.addManifestEntry("Bundle-Classpath", sb.toString());
+	}
+
+	/**
+	 * Iterate over the declared exports from the POM, verify that they are
+	 * present, add the uses clause if necessary and finally add the manifest
+	 * entry.
+	 * 
+	 * @param contained Set of contained packages
+	 * @param exports Map with the export clauses from the POM
+	 * @param uses Map with use clauses
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredExports(Map exports, Set contained)
+			throws MojoExecutionException {
+		Set declaredExports = exports.keySet();
+		for (Iterator i = declaredExports.iterator(); i.hasNext();) {
+			String pack = (String) i.next();
+			if (!contained.contains(pack)) {
+				getLog()
+						.error("[OSGi] EXPORTED PACKAGE NOT IN BUNDLE: " + pack);
+				throw new MojoExecutionException(
+						"Exported Package not found in bundle or JARs on bundle class path "
+								+ pack);
+			}
+
+		}
+	}
+
+	/**
+	 * Print out the export headers after adding the uses clause.
+	 * 
+	 * @param exports
+	 * @param uses
+	 * @throws MojoExecutionException
+	 */
+	void createExportHeader(Map exports, Map uses)
+			throws MojoExecutionException {
+		if (exports.size() > 0) {
+			Set declaredExports = exports.keySet();
+			for (Iterator i = declaredExports.iterator(); i.hasNext();) {
+				String pack = (String) i.next();
+				Map clause = (Map) exports.get(pack);
+
+				if (bundleManifestVersion >= 2) {
+					Set t = (Set) uses.get(pack);
+					if (t != null && !t.isEmpty()) {
+						StringBuffer sb = new StringBuffer();
+						String del = "\"";
+						for (Iterator u = t.iterator(); u.hasNext();) {
+							String usedPackage = (String) u.next();
+							if (!usedPackage.equals(pack)) {
+								sb.append(del);
+								sb.append(usedPackage);
+								del = ",";
+							}
+						}
+						sb.append("\"");
+						clause.put("uses:", sb.toString());
+					}
+				}
+			}
+			archiveConfig.addManifestEntry(
+					"Export-Package",
+					printClauses(exports));
+		}
+	}
+
+	/**
+	 * Verify that the declared imports match the referred packages.
+	 * 
+	 * @param referred referred package
+	 * @param imports imported packages from POM
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredImports(Set referred, Map imports)
+			throws MojoExecutionException {
+		Set declaredImports = imports.keySet();
+		Set test = new HashSet(referred);
+		test.removeAll(declaredImports);
+		for (Iterator m = test.iterator(); m.hasNext();) {
+			Object o = m.next();
+			if(o.equals("org.apache.felix.ipojo")) { break; } // Skip iPOJO, it will be add at the end of the packaging
+			getLog().warn("[OSGi] MISSING IMPORT: " + o);
+			//throw new MojoExecutionException("Missing Import " + o);
+		}
+
+		test = new HashSet(declaredImports);
+		test.removeAll(referred);
+		for (Iterator m = test.iterator(); m.hasNext();) {
+			getLog().warn("[OSGi] SUPERFLUOUS IMPORT: " + m.next());
+			getLog()
+					.warn(
+							"[OSGi] Removing the POM Import-Package element will automatically generate the import clauses");
+		}
+	}
+
+	/**
+	 * Standard OSGi header parser. This parser can handle the format clauses
+	 * ::= clause ( ',' clause ) + clause ::= name ( ';' name ) (';' key '='
+	 * value )
+	 * 
+	 * This is mapped to a Map { name => Map { attr|directive => value } }
+	 * 
+	 * @param value
+	 * @return
+	 * @throws MojoExecutionException
+	 */
+	static Map parseHeader(String value) throws MojoExecutionException {
+		if (value == null || value.trim().length() == 0)
+			return null;
+
+		Map result = new HashMap();
+		QuotedTokenizer qt = new QuotedTokenizer(value, ";=,");
+		char del;
+		do {
+			boolean hadAttribute = false;
+			Map clause = new HashMap();
+			List aliases = new ArrayList();
+			aliases.add(qt.nextToken());
+			del = qt.getSeparator();
+			while (del == ';') {
+				String adname = qt.nextToken();
+				if (qt.getSeparator() != '=') {
+					if (hadAttribute)
+						throw new MojoExecutionException(
+								"Header contains name field after attribute or directive: "
+										+ adname + " from " + value);
+					aliases.add(adname);
+				}
+				else {
+					String advalue = qt.nextToken();
+					clause.put(adname, advalue);
+					del = qt.getSeparator();
+					hadAttribute = true;
+				}
+			}
+			for (Iterator i = aliases.iterator(); i.hasNext();) {
+				result.put(i.next(), clause);
+			}
+		} while (del == ',');
+		return result;
+	}
+
+	/**
+	 * Create the import header, taking into account R4 automatic import clauses
+	 * for the exports.
+	 * 
+	 * @param referred
+	 * @param contained
+	 */
+	void createImportHeader(Set referred, Set contained) {
+		if (referred.isEmpty())
+			return;
+
+		referred = new TreeSet(referred);
+
+		if (bundleManifestVersion > 1) {
+			referred.addAll(contained);
+		}
+
+		StringBuffer sb = new StringBuffer();
+		String del = "";
+
+		for (Iterator i = referred.iterator(); i.hasNext();) {
+			sb.append(del);
+			sb.append(i.next());
+			del = ", ";
+		}
+		
+		// Add handler import
+		for(int j = 0; j < namespaces.length; j++) {
+			for(int k = 0; k < namespaces[j].length; k++) {
+				if(! namespaces[j][k].equals("")) {
+					int lastIndex = namespaces[j][k].lastIndexOf('.');
+					String ns = namespaces[j][k].substring(0, lastIndex);
+					sb.append(del);
+					sb.append(ns);
+					del = ", ";
+				}
+			}
+		}
+		
+		archiveConfig.addManifestEntry("Import-Package", sb.toString());
+		getLog().info("Set Imports to : " + sb.toString());
+	}
+
+	/**
+	 * Calculate the bundle class path based on the list of JARs in our bundle.
+	 * This list includes outselves. We also calculate the Bundle-Classpath
+	 * header (a bit clumsy) This is a bit cheap, so maybe this needs to be
+	 * changed TODO
+	 * 
+	 * @param mainJar
+	 * @param sb
+	 * @return
+	 */
+	List getBundleClassPath(Jar mainJar) {
+		List result = new ArrayList();
+		for (Iterator i = mainJar.resources.keySet().iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			Object resource = mainJar.resources.get(path);
+			if (resource instanceof Jar) {
+				result.add(path);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * We traverse through al the classes that we can find and calculate the
+	 * contained and referred set and uses.
+	 * 
+	 * @param jar
+	 * @param contained
+	 * @param referred
+	 * @param uses
+	 */
+	void analyzeJar(Jar jar, Set contained, Set referred, Map uses) {
+		String prefix = "";
+		Set set = jar.getEntryPaths(prefix);
+		for (Iterator r = set.iterator(); r.hasNext();) {
+			String path = (String) r.next();
+			Object resource = jar.getEntry(path);
+			if (resource instanceof Clazz) {
+				Clazz clazz = (Clazz) resource;
+				String pathOfClass = path.substring(prefix.length());
+				String pack = Clazz.getPackage(pathOfClass);
+				contained.add(pack);
+				referred.addAll(clazz.getReferred());
+
+				// Add all the used packages
+				// to this package
+				Set t = (Set) uses.get(pack);
+				if (t == null)
+					uses.put(pack, t = new HashSet());
+				t.addAll(clazz.getReferred());
+				t.remove(pack);
+			}
+		}
+	}
+
+	/**
+	 * Print a standard Map based OSGi header.
+	 * 
+	 * @param exports map { name => Map { attribute|directive => value } }
+	 * @return the clauses
+	 */
+
+	String printClauses(Map exports) {
+		StringBuffer sb = new StringBuffer();
+		String del = "";
+		for (Iterator i = exports.keySet().iterator(); i.hasNext();) {
+			String name = (String) i.next();
+			Map map = (Map) exports.get(name);
+			sb.append(del);
+			sb.append(name);
+
+			for (Iterator j = map.keySet().iterator(); j.hasNext();) {
+				String key = (String) j.next();
+				String value = (String) map.get(key);
+				sb.append(";");
+				sb.append(key);
+				sb.append("=");
+				sb.append(value);
+			}
+			del = ", ";
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Check if the BundleManifest version is set correctly, base the manifest
+	 * version on it.
+	 * 
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredBundleManifestVersion() throws MojoExecutionException {
+		String mfv = osgiManifest.getBundleManifestVersion();
+		if (mfv != null && mfv.trim().length() != 0) {
+			try {
+				bundleManifestVersion = Integer.parseInt(mfv);
+				if (bundleManifestVersion != 2)
+					throw new MojoExecutionException(
+							"Bundle-ManifestVersion must be 2, it is " + mfv);
+			}
+			catch (Exception e) {
+				throw new MojoExecutionException(
+						"Bundle-ManifestVersion must be an integer: " + mfv);
+			}
+		}
+	}
+
+	/**
+	 * TODO: Decide if we accept merging of entire manifest.mf files Here's a
+	 * big question to make a final decision at some point: Do accept merging of
+	 * manifest entries located in some file somewhere in the project directory?
+	 * If so, do we allow both file and configuration based entries to be
+	 * specified simultaneously and how do we merge these?
+	 */
+	private void addManifestFile() {
+		if (manifestFile != null) {
+			File file = new File(project.getBasedir().getAbsolutePath(),
+					manifestFile);
+			getLog().info(
+					"Manifest file: " + file.getAbsolutePath()
+							+ " will be used");
+			archiveConfig.setManifestFile(file);
+		}
+		else {
+			getLog().info("No manifest file specified. Default will be used.");
+		}
+	}
+
+	/**
+	 * Look for any OSGi specified manifest entries in the maven-osgi-plugin
+	 * configuration section of the POM. If we find some, then add them to the
+	 * target artifact's manifest.
+	 */
+	private void addManifestEntries() {
+		if (osgiManifest != null && osgiManifest.getEntries().size() > 0) {
+			Map entries = osgiManifest.getEntries();
+
+			getLog().info(
+					"Bundle manifest will be modified with the following entries: "
+							+ entries.toString());
+			archiveConfig.addManifestEntries(entries);
+		}
+		else {
+			getLog()
+					.info(
+							"No OSGi bundle manifest entries have been specified in the POM.");
+		}
+	}
+
+	/**
+	 * We are going to iterate through the POM's specified JAR dependencies. If
+	 * a dependency has a scope of either RUNTIME or COMPILE, then we'll JAR
+	 * them up inside the OSGi bundle artifact. We will then add the
+	 * Bundle-Classpath manifest entry.
+	 */
+	private void addEmbeddedJars() throws MojoExecutionException {
+		Set artifacts = project.getArtifacts();
+
+		for (Iterator it = artifacts.iterator(); it.hasNext();) {
+			Artifact artifact = (Artifact) it.next();
+			if (!Artifact.SCOPE_PROVIDED.equals(artifact.getScope())
+					&& !Artifact.SCOPE_TEST.equals(artifact.getScope())) {
+				String type = artifact.getType();
+
+				if ("jar".equals(type)) {
+					File depFile = artifact.getFile();
+
+					try {
+						FileUtils.copyFileToDirectory(depFile, outputDirectory);
+
+					}
+					catch (Exception e) {
+						String errmsg = "Error copying "
+								+ depFile.getAbsolutePath() + " to "
+								+ outputDirectory.getAbsolutePath();
+						throw new MojoExecutionException(errmsg, e);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Auto-set the bundle version.
+	 */
+	private void addBundleVersion() {
+		// Maven uses a '-' to separate the version qualifier,
+		// while OSGi uses a '.', so we need to convert to a '.'
+		StringBuffer sb = new StringBuffer(project.getVersion());
+		if (sb.indexOf("-") >= 0) {
+			sb.setCharAt(sb.indexOf("-"), '.');
+		}
+		archiveConfig.addManifestEntry("Bundle-Version", sb.toString());
+	}
+
+	/**
+	 * Returns a string array of the includes to be used when assembling/copying
+	 * the war.
+	 * 
+	 * @return an array of tokens to include
+	 */
+	private String[] getIncludes() {
+		return new String[] {jarSourceIncludes};
+	}
+
+	/**
+	 * Returns a string array of the excludes to be used when assembling/copying
+	 * the jar.
+	 * 
+	 * @return an array of tokens to exclude
+	 */
+	private String[] getExcludes() {
+		List excludeList = new ArrayList(FileUtils.getDefaultExcludesAsList());
+
+		if (jarSourceExcludes != null && !"".equals(jarSourceExcludes)) {
+			excludeList.add(jarSourceExcludes);
+		}
+
+		return (String[]) excludeList.toArray(EMPTY_STRING_ARRAY);
+	}
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiManifest.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiManifest.java
new file mode 100644
index 0000000..a7ff801
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiManifest.java
@@ -0,0 +1,550 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.plugin;
+
+import java.util.Properties;
+
+/**
+ * Hold values for an OSGi jar "bundle" manifest.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Apache Felix Project</a>
+ * @version $Rev$, $Date$
+ */
+public class OsgiManifest
+{
+    /**
+     * Bundle manifest header constants from the OSGi R4 framework constants.
+     */
+    private static final String BUNDLE_CATEGORY = "Bundle-Category";
+    // private static final String BUNDLE_CLASSPATH = "Bundle-ClassPath";
+    private static final String BUNDLE_COPYRIGHT = "Bundle-Copyright";
+    private static final String BUNDLE_DESCRIPTION = "Bundle-Description";
+    private static final String BUNDLE_NAME = "Bundle-Name";
+    private static final String BUNDLE_NATIVECODE = "Bundle-NativeCode";
+    private static final String EXPORT_PACKAGE = "Export-Package";
+    private static final String EXPORT_SERVICE = "Export-Service";
+    private static final String IMPORT_PACKAGE = "Import-Package";
+    private static final String DYNAMICIMPORT_PACKAGE = "DynamicImport-Package";
+    private static final String IMPORT_SERVICE = "Import-Service";
+    private static final String BUNDLE_VENDOR = "Bundle-Vendor";
+    private static final String BUNDLE_VERSION = "Bundle-Version";
+    private static final String BUNDLE_DOCURL = "Bundle-DocURL";
+    private static final String BUNDLE_CONTACTADDRESS = "Bundle-ContactAddress";
+    private static final String BUNDLE_ACTIVATOR = "Bundle-Activator";
+    private static final String BUNDLE_UPDATELOCATION = "Bundle-UpdateLocation";
+    private static final String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
+    private static final String BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName";
+    private static final String BUNDLE_LOCALIZATION = "Bundle-Localization";
+    private static final String REQUIRE_BUNDLE = "Require-Bundle";
+    private static final String FRAGMENT_HOST = "Fragment-Host";
+    private static final String BUNDLE_MANIFESTVERSION = "Bundle-ManifestVersion";
+
+    private static final String BUNDLE_URL = "Bundle-URL";
+    private static final String BUNDLE_SOURCE = "Bundle-Source";
+    private static final String BUNDLE_DATE = "Bundle-Date";
+    private static final String METADATA_LOCATION = "Metadata-Location";
+    
+    // iPOJO Manifest Headers
+    private static final String IPOJO_METADATA ="iPOJO-Metadata";
+    private static final String IPOJO_COMPONENTS ="iPOJO-Components";
+
+    /**
+     * Instance variables corresponding to the R4 framework manifest headers
+     */
+    private String bundleCategory;
+    // private String bundleClassPath;
+    private String bundleCopyright;
+    private String bundleDescription;
+    private String bundleName;
+    private String bundleNativeCode;
+    private String exportPackage;
+    private String exportService;
+    private String importPackage;
+    private String dynamicImportPackage;
+    private String importService;
+    private String bundleVendor;
+    private String bundleVersion;
+    private String bundleDocUrl;
+    private String bundleContactAddress;
+    private String bundleActivator;
+    private String bundleUpdateLocation;
+    private String bundleRequiredExecutionEnvironment;
+    private String bundleSymbolicName;
+    private String bundleLocalization;
+    private String requireBundle;
+    private String fragmentHost;
+    private String bundleManifestVersion;
+
+    /**
+     * Instance variables supporting non-framework manifest headers
+     */
+    private String bundleUrl;
+    private String bundleSource;
+    private String bundleDate;
+    private String metadataLocation;
+    
+    /**
+     * iPOJO Headers
+     */
+    private String iPOJOMetadata;
+    private String iPOJOComponents;
+
+    private Properties entries = new Properties();
+
+    public Properties getEntries()
+    {
+        if ( getBundleCategory() != null )
+        {
+            entries.put( BUNDLE_CATEGORY, getBundleCategory() );
+        }
+
+        /*
+         if (getBundleClassPath() != null)
+         {
+         entries.put(BUNDLE_CLASSPATH, getBundleClassPath());
+         }
+         */
+
+        if ( getBundleCopyright() != null )
+        {
+            entries.put( BUNDLE_COPYRIGHT, getBundleCopyright() );
+        }
+
+        if ( getBundleDescription() != null )
+        {
+            entries.put( BUNDLE_DESCRIPTION, getBundleDescription() );
+        }
+
+        if ( getBundleName() != null )
+        {
+            entries.put( BUNDLE_NAME, getBundleName() );
+        }
+
+        if ( getBundleNativeCode() != null )
+        {
+            entries.put( BUNDLE_NATIVECODE, getBundleNativeCode() );
+        }
+
+        if ( getExportPackage() != null )
+        {
+            entries.put( EXPORT_PACKAGE, getExportPackage() );
+        }
+
+        if ( getExportService() != null )
+        {
+            entries.put( EXPORT_SERVICE, getExportService() );
+        }
+
+        if ( getImportPackage() != null )
+        {
+            entries.put( IMPORT_PACKAGE, getImportPackage() );
+        }
+
+        if ( getDynamicImportPackage() != null )
+        {
+            entries.put( DYNAMICIMPORT_PACKAGE, getDynamicImportPackage() );
+        }
+
+        if ( getImportService() != null )
+        {
+            entries.put( IMPORT_SERVICE, getImportService() );
+        }
+
+        if ( getBundleVendor() != null )
+        {
+            entries.put( BUNDLE_VENDOR, getBundleVendor() );
+        }
+
+        if ( getBundleVersion() != null )
+        {
+            entries.put( BUNDLE_VERSION, getBundleVersion() );
+        }
+
+        if ( getBundleDocUrl() != null )
+        {
+            entries.put( BUNDLE_DOCURL, getBundleDocUrl() );
+        }
+
+        if ( getBundleContactAddress() != null )
+        {
+            entries.put( BUNDLE_CONTACTADDRESS, getBundleContactAddress() );
+        }
+
+        if ( getBundleActivator() != null )
+        {
+            entries.put( BUNDLE_ACTIVATOR, getBundleActivator() );
+        }
+
+        if ( getBundleUpdateLocation() != null )
+        {
+            entries.put( BUNDLE_UPDATELOCATION, getBundleUpdateLocation() );
+        }
+
+        if ( getBundleRequiredExecutionEnvironment() != null )
+        {
+            entries.put( BUNDLE_REQUIREDEXECUTIONENVIRONMENT, getBundleRequiredExecutionEnvironment() );
+        }
+
+        if ( getBundleSymbolicName() != null )
+        {
+            entries.put( BUNDLE_SYMBOLICNAME, getBundleSymbolicName() );
+        }
+
+        if ( getBundleLocalization() != null )
+        {
+            entries.put( BUNDLE_LOCALIZATION, getBundleLocalization() );
+        }
+
+        if ( getRequireBundle() != null )
+        {
+            entries.put( REQUIRE_BUNDLE, getRequireBundle() );
+        }
+
+        if ( getFragmentHost() != null )
+        {
+            entries.put( FRAGMENT_HOST, getFragmentHost() );
+        }
+
+        if ( getBundleManifestVersion() != null )
+        {
+            entries.put( BUNDLE_MANIFESTVERSION, getBundleManifestVersion() );
+        }
+
+        if ( getBundleUrl() != null )
+        {
+            entries.put( BUNDLE_URL, getBundleUrl() );
+        }
+
+        if ( getBundleSource() != null )
+        {
+            entries.put( BUNDLE_SOURCE, getBundleSource() );
+        }
+
+        if ( getBundleDate() != null )
+        {
+            entries.put( BUNDLE_DATE, getBundleDate() );
+        }
+
+        if ( getMetadataLocation() != null )
+        {
+            entries.put( METADATA_LOCATION, getMetadataLocation() );
+        }
+        
+        // iPOJO Headers : 
+        if ( getiPOJOMetadata() != null )
+        {
+            entries.put( IPOJO_METADATA, getiPOJOMetadata() );
+        }
+        
+        if( getiPOJOComponents() != null )
+        {
+        	entries.put( IPOJO_COMPONENTS, getiPOJOComponents() );
+        }
+
+        return entries;
+    }
+
+    public String getBundleCategory()
+    {
+        return bundleCategory;
+    }
+
+    public void setBundleCategory( String bundleCategory )
+    {
+        this.bundleCategory = bundleCategory;
+    }
+
+    /*
+     public String getBundleClasspath()
+     {
+     return bundleClasspath;
+     }
+
+     public void setBundleClasspath(String bundleClasspath)
+     {
+     this.bundleClasspath = bundleClasspath;
+     }
+     */
+
+    public String getBundleCopyright()
+    {
+        return bundleCopyright;
+    }
+
+    public void setBundleCopyright( String bundleCopyright )
+    {
+        this.bundleCopyright = bundleCopyright;
+    }
+
+    public String getBundleDescription()
+    {
+        return bundleDescription;
+    }
+
+    public void setBundleDescription( String bundleDescription )
+    {
+        this.bundleDescription = bundleDescription;
+    }
+
+    public String getBundleName()
+    {
+        return bundleName;
+    }
+
+    public void setBundleName( String bundleName )
+    {
+        this.bundleName = bundleName;
+    }
+
+    public String getBundleNativeCode()
+    {
+        return bundleNativeCode;
+    }
+
+    public void setBundleNativeCode( String bundleNativeCode )
+    {
+        this.bundleNativeCode = bundleNativeCode;
+    }
+
+    public String getExportPackage()
+    {
+        return exportPackage;
+    }
+
+    public void setExportPackage( String exportPackage )
+    {
+        this.exportPackage = exportPackage;
+    }
+
+    public String getExportService()
+    {
+        return exportService;
+    }
+
+    public void setExportService( String exportService )
+    {
+        this.exportService = exportService;
+    }
+
+    public String getImportPackage()
+    {
+        return importPackage;
+    }
+
+    public void setImportPackage( String importPackage )
+    {
+        this.importPackage = importPackage;
+    }
+
+    public String getDynamicImportPackage()
+    {
+        return dynamicImportPackage;
+    }
+
+    public void setDynamicImportPackage( String dynamicImportPackage )
+    {
+        this.dynamicImportPackage = dynamicImportPackage;
+    }
+
+    public String getImportService()
+    {
+        return importService;
+    }
+
+    public void setImportService( String importService )
+    {
+        this.importService = importService;
+    }
+
+    public String getBundleVendor()
+    {
+        return bundleVendor;
+    }
+
+    public void setBundleVendor( String bundleVendor )
+    {
+        this.bundleVendor = bundleVendor;
+    }
+
+    public String getBundleVersion()
+    {
+        return bundleVersion;
+    }
+
+    public void setBundleVersion( String bundleVersion )
+    {
+        this.bundleVersion = bundleVersion;
+    }
+
+    public String getBundleDocUrl()
+    {
+        return bundleDocUrl;
+    }
+
+    public void setBundleDocUrl( String bundleDocUrl )
+    {
+        this.bundleDocUrl = bundleDocUrl;
+    }
+
+    public String getBundleContactAddress()
+    {
+        return bundleContactAddress;
+    }
+
+    public void setBundleContactAddress( String bundleContactAddress )
+    {
+        this.bundleContactAddress = bundleContactAddress;
+    }
+
+    public String getBundleActivator()
+    {
+        return bundleActivator;
+    }
+
+    public void setBundleActivator( String bundleActivator )
+    {
+        this.bundleActivator = bundleActivator;
+    }
+
+    public String getBundleUpdateLocation()
+    {
+        return bundleUpdateLocation;
+    }
+
+    public void setBundleUpdateLocation( String bundleUpdateLocation )
+    {
+        this.bundleUpdateLocation = bundleUpdateLocation;
+    }
+
+    public String getBundleRequiredExecutionEnvironment()
+    {
+        return bundleRequiredExecutionEnvironment;
+    }
+
+    public void setBundleRequiredExecutionEnvironment( String bundleRequiredExecutionEnvironment )
+    {
+        this.bundleRequiredExecutionEnvironment = bundleRequiredExecutionEnvironment;
+    }
+
+    public String getBundleSymbolicName()
+    {
+        return bundleSymbolicName;
+    }
+
+    public void setBundleSymbolicName( String bundleSymbolicName )
+    {
+        this.bundleSymbolicName = bundleSymbolicName;
+    }
+
+    public String getBundleLocalization()
+    {
+        return bundleLocalization;
+    }
+
+    public void setBundleLocalization( String bundleLocalization )
+    {
+        this.bundleLocalization = bundleLocalization;
+    }
+
+    public String getRequireBundle()
+    {
+        return requireBundle;
+    }
+
+    public void setRequireBundle( String requireBundle )
+    {
+        this.requireBundle = requireBundle;
+    }
+
+    public String getFragmentHost()
+    {
+        return fragmentHost;
+    }
+
+    public void setFragmentHost( String fragmentHost )
+    {
+        this.fragmentHost = fragmentHost;
+    }
+
+    public String getBundleManifestVersion()
+    {
+        return bundleManifestVersion;
+    }
+
+    public void setBundleManifestVersion( String bundleManifestVersion )
+    {
+        this.bundleManifestVersion = bundleManifestVersion;
+    }
+
+    public String getBundleUrl()
+    {
+        return bundleUrl;
+    }
+
+    public void setBundleUrl( String bundleUrl )
+    {
+        this.bundleUrl = bundleUrl;
+    }
+
+    public String getBundleSource()
+    {
+        return bundleSource;
+    }
+
+    public void setBundleSource( String bundleSource )
+    {
+        this.bundleSource = bundleSource;
+    }
+
+    public String getBundleDate()
+    {
+        return bundleDate;
+    }
+
+    public void setBundleDate( String bundleDate )
+    {
+        this.bundleDate = bundleDate;
+    }
+
+    public String getMetadataLocation()
+    {
+        return metadataLocation;
+    }
+
+    public void setMetadataLocation( String metadataLocation )
+    {
+        this.metadataLocation = metadataLocation;
+    }
+    
+    // iPOJO Headers
+    public String getiPOJOMetadata() {
+    	return iPOJOMetadata;
+    }
+    
+    public void setiPOJOMetadata( String metadata) {
+    	this.iPOJOMetadata = metadata;
+    }
+    
+    public String getiPOJOComponents() {
+    	return iPOJOComponents;
+    }
+    
+    public void setiPOJOComponents( String metadata) {
+    	this.iPOJOComponents = metadata;
+    }
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/QuotedTokenizer.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/QuotedTokenizer.java
new file mode 100644
index 0000000..da4476b
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/QuotedTokenizer.java
@@ -0,0 +1,114 @@
+package org.apache.felix.ipojo.plugin;
+
+import java.util.*;
+
+public class QuotedTokenizer {
+	String	string;
+	int		index				= 0;
+	String	separators;
+	boolean	returnTokens;
+	boolean	ignoreWhiteSpace	= true;
+	String	peek;
+	char	separator;
+
+	public QuotedTokenizer(String string, String separators, boolean returnTokens ) {
+		if ( string == null )
+			throw new IllegalArgumentException("string argument must be not null");
+		this.string = string;
+		this.separators = separators;
+		this.returnTokens = returnTokens;
+	}
+	public QuotedTokenizer(String string, String separators) {
+		this(string,separators,false);
+	}
+
+	public String nextToken(String separators) {
+		separator = 0;
+		if ( peek != null ) {
+			String tmp = peek;
+			peek = null;
+			return tmp;
+		}
+		
+		if ( index == string.length())
+			return null;
+		
+		StringBuffer sb = new StringBuffer();
+
+		while (index < string.length()) {
+			char c = string.charAt(index++);
+
+			if ( Character.isWhitespace(c)) {
+				if ( index == string.length())
+					break;
+				else
+					continue;
+			}
+			
+			if (separators.indexOf(c) >= 0) {
+				if (returnTokens)
+					peek = Character.toString(c);
+				else
+					separator = c;
+				break;
+			}
+
+			switch (c) {
+				case '"' :
+				case '\'' :
+					quotedString(sb, c);
+					break;
+
+				default :
+					sb.append(c);
+			}
+		}
+		String result = sb.toString().trim();
+		if ( result.length()==0 && index==string.length())
+			return null;
+		return result;
+	}
+
+	public String nextToken() {
+		return nextToken(separators);
+	}
+
+	private void quotedString(StringBuffer sb, char c) {
+		char quote = c;
+		while (index < string.length()) {
+			c = string.charAt(index++);
+			if (c == quote)
+				break;
+			if (c == '\\' && index < string.length()
+					&& string.charAt(index + 1) == quote)
+				c = string.charAt(index++);
+			sb.append(c);
+		}
+	}
+
+	public String[] getTokens() {
+		return getTokens(0);
+	}
+
+	private String [] getTokens(int cnt){
+		String token = nextToken();
+		if ( token == null ) 
+			return new String[cnt];
+		
+		String result[] = getTokens(cnt+1);
+		result[cnt]=token;
+		return result;
+	}
+
+	public char getSeparator() { return separator; }
+	
+	public List getTokenSet() {
+		List list = new ArrayList();
+		String token = nextToken();
+		while ( token != null ) {
+			list.add(token);
+			token = nextToken();
+		}
+		return list;
+	}
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/archetype.xml b/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/archetype.xml
new file mode 100644
index 0000000..ed1f74c
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/archetype.xml
@@ -0,0 +1,9 @@
+<archetype>
+	<id>org.apache.felix.ipojo.plugin</id>
+	<sources>
+		<source>src/main/java/source.txt</source>
+	</sources>
+	<resources>
+		<resource>src/main/resources/metadata.xml</resource>
+	</resources>
+</archetype>
\ No newline at end of file
diff --git a/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/plexus/components.xml b/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 0000000..800acd1
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,40 @@
+<component-set>
+  <components>
+    <component>
+      <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+      <role-hint>ipojo-bundle</role-hint>
+      <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+      <configuration>
+        <lifecycles>
+          <lifecycle>
+            <id>default</id>
+            <!-- START SNIPPET: ipojo-bundle-lifecycle -->
+            <phases>
+              <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
+              <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
+              <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources>
+              <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
+              <test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
+              <package>org.apache.felix:org.apache.felix.ipojo.plugin:ipojo-bundle</package>
+              <install>org.apache.maven.plugins:maven-install-plugin:install</install>
+              <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
+            </phases>
+            <!-- END SNIPPET: ipojo-bundle-lifecycle -->
+          </lifecycle>
+        </lifecycles>
+      </configuration>
+    </component>
+    <component>
+      <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+      <role-hint>ipojo-bundle</role-hint>
+      <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+      <configuration>
+        <type>ipojo-bundle</type>
+        <includesDependencies>true</includesDependencies>
+        <language>java</language>
+        <extension>jar</extension>
+        <addedToClasspath>true</addedToClasspath>
+      </configuration>
+    </component>
+  </components>
+</component-set>
diff --git a/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/pom.xml b/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/pom.xml
new file mode 100644
index 0000000..8dc2fa1
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/pom.xml
@@ -0,0 +1,33 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>ipojo-bundle</packaging>
+  <groupId>${groupId}</groupId>
+  <artifactId>${artifactId}</artifactId>
+  <version>${version}</version>
+  <name>$YOUR_PROJECT_NAME</name>
+  
+  <pluginRepositories>
+    <pluginRepository>
+      <id>iPOJO.repository</id>
+      <name>iPOJO Repository</name>
+      <url>http://www-adele.imag.fr/~escoffie/repository</url>
+    </pluginRepository>
+  </pluginRepositories>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.ipojo</groupId>
+        <artifactId>org.apache.felix.ipojo.plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>${pom.name}</bundleName>
+            <bundleDescription>$YOUR_BUNDLE_DESCRIPTION</bundleDescription>
+            <iPOJOMetadata>metadata.xml</iPOJOMetadata>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/java/source.txt b/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/java/source.txt
new file mode 100644
index 0000000..0198756
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/java/source.txt
@@ -0,0 +1 @@
+PUT YOUR SOURCE FILES HERE
\ No newline at end of file
diff --git a/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml b/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml
new file mode 100644
index 0000000..9b9615d
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<iPOJO>
+	<component className="$YOUR_COMPONENT_CLASS">
+   
+	</component>
+</iPOJO>
\ No newline at end of file
diff --git a/org.apache.felix.ipojo/pom.xml b/org.apache.felix.ipojo/pom.xml
new file mode 100644
index 0000000..defb4b6
--- /dev/null
+++ b/org.apache.felix.ipojo/pom.xml
@@ -0,0 +1,54 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>osgi-bundle</packaging>
+  <name>Apache Felix iPOJO</name>
+  <artifactId>org.apache.felix.ipojo</artifactId>
+  <version>0.6.0-SNAPSHOT</version>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm</artifactId>
+      <version>2.2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.plugins</groupId>
+        <artifactId>maven-osgi-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>iPOJO</bundleName>
+            <bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
+            <bundleVendor>Clement ESCOFFIER</bundleVendor>
+            <bundleDescription> iPOJO </bundleDescription>
+            <importPackage>
+              org.osgi.framework, org.osgi.service.cm
+            </importPackage>
+            <exportPackage>
+              org.apache.felix.ipojo, org.apache.felix.ipojo.metadata, org.apache.felix.ipojo.architecture, org.apache.felix.ipojo.parser, org.osgi.service.cm
+            </exportPackage>
+            <bundleActivator>org.apache.felix.ipojo.DummyActivator</bundleActivator>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
new file mode 100644
index 0000000..827be0d
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
@@ -0,0 +1,236 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.io.IOException;
+import java.util.Dictionary;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * iPOJO generic activator.
+ * Date : 31 mars 2006
+ * @author clement escoffier
+ */
+public class Activator implements BundleActivator {
+
+
+	// STATIC
+	/**
+	 * The iPOJO static logger. This logger is used by each iPOJO instance.
+	 */
+	private static Logger m_logger = Logger.getLogger("org.apache.felix.ipojo");
+
+	 /**
+     * @return Returns the static ipojo logger : org.apache.felix.ipojo
+     */
+    public static Logger getLogger() {
+        return Activator.m_logger;
+    }
+    // END STATIC
+
+    // NON STATIC PART
+
+    /**
+     * The m_bundle context.
+     * m_bundleContext : BundleContext
+     */
+    private BundleContext m_bundleContext = null;
+
+    /**
+     * The component manager for this activator.
+     * m_handler : ComponentManagerFactory
+     */
+    private ComponentManagerFactory[] m_factories;
+
+    // Field accessors  :
+
+    /**
+     * @return the m_bundle context
+     */
+    public BundleContext getBundleContext() {
+        return m_bundleContext;
+    }
+
+    /**
+     * Add a component manager factory to the factory list.
+     * @param cm : the new component metadata.
+     */
+    public void addComponentFactory(Element cm) {
+    	// Create the factory :
+    	ComponentManagerFactory factory = new ComponentManagerFactory(this, cm);
+
+    	// If the factory array is not empty add the new factory at the end
+        if (m_factories.length != 0) {
+            ComponentManagerFactory[] newFactory = new ComponentManagerFactory[m_factories.length + 1];
+            System.arraycopy(m_factories, 0, newFactory, 0, m_factories.length);
+            newFactory[m_factories.length] = factory;
+            m_factories = newFactory;
+        }
+        // Else create an array of size one with the new Factory
+        else { m_factories = new ComponentManagerFactory[] {factory}; }
+    }
+
+    /**
+     * Remove a component manager factory to the factory list.
+     * @param factory : the componet facotry to remove
+     */
+    public void removeComponentFactory(ComponentManagerFactory factory) {
+
+        int idx = -1;
+        for (int i = 0; i < m_factories.length; i++) {
+            if (m_factories[i] == factory) {
+                idx = i;
+                break;
+            }
+        }
+
+        if (idx >= 0) {
+            // If this is the factory, then point to empty list.
+            if ((m_factories.length - 1) == 0) {
+            	m_factories = new ComponentManagerFactory[0];
+            }
+            // Otherwise, we need to do some array copying.
+            else {
+                ComponentManagerFactory[] newFactories = new ComponentManagerFactory[m_factories.length - 1];
+                System.arraycopy(m_factories, 0, newFactories, 0, idx);
+                if (idx < newFactories.length) {
+                    System.arraycopy(m_factories, idx + 1, newFactories, idx, newFactories.length - idx);
+                }
+                m_factories = newFactories;
+            }
+        }
+    }
+
+    // End field accesors
+
+    // Constructors :
+
+    /**
+     * Constructor used by Felix.
+     */
+    public Activator() {
+        super();
+        m_factories = new ComponentManagerFactory[0];
+    }
+
+    // End constuctors
+
+    // Bundle Lifecycle CallBack
+
+    /**
+     * Start method.
+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     * @param bc : the m_bundle context to use to manage the component.
+     * @throws Exception : when a problem occurs
+     */
+    public void start(final BundleContext bc) throws Exception {
+      m_bundleContext = bc;
+
+      // Set the trace level
+      String level = System.getProperty("ipojo.loglevel");
+      if (level != null) {
+         if (level.equals("ALL")) {
+        	 Activator.getLogger().setLevel(Level.ALL);
+         }
+         if (level.equals("FINEST")) {
+        	 Activator.getLogger().setLevel(Level.FINEST);
+         }
+         if (level.equals("WARNING")) {
+        	 Activator.getLogger().setLevel(Level.WARNING);
+         }
+      }
+      else { Activator.getLogger().setLevel(IPojoConfiguration.LOG_LEVEL); }
+
+      try {
+          parse();
+      } catch (Exception e) {
+    	  Activator.getLogger().log(Level.SEVERE, "Parse error for the bundle " + m_bundleContext.getBundle().getBundleId() + " : " + e.getMessage());
+         return;
+      }
+      Activator.getLogger().log(Level.INFO, "[Bundle" + m_bundleContext.getBundle().getBundleId() + "] Called start after the parsing");
+
+      // Call the internal start method
+      start();
+
+    }
+
+    /**
+     * Stop method.
+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     * @param arg0 : the m_bundle context
+     * @throws Exception : ???
+     */
+    public void stop(BundleContext arg0) throws Exception {
+        for (int i = 0; i < m_factories.length; i++) {
+        	ComponentManagerFactory factory = m_factories[i];
+        	factory.stop();
+        }
+    }
+
+    // End Bundle Lifecycle CallBack
+
+    // Parsing methods :
+
+    /**
+     * Parse the file who is at the Metadata-Location place, manipulate the bytecode of the component implementation class
+     * and set the manager.
+     * @throws IOException
+     * @throws ParseException
+     */
+    private void parse() throws IOException, ParseException {
+
+       String componentClasses = (String)m_bundleContext.getBundle().getHeaders().get("iPOJO-Components");
+        if (componentClasses != null) {
+        	parseManifest(m_bundleContext.getBundle().getHeaders());
+        } else {
+        	Activator.getLogger().log(Level.SEVERE, "[Bundle" + m_bundleContext.getBundle().getBundleId() + "] Components-Metadata are not in the manifest");
+        	throw new ParseException("[Bundle" + m_bundleContext.getBundle().getBundleId() + "] Component-Metadata are not in the manifest");
+        }
+    }
+
+    private void parseManifest(Dictionary dict) throws ParseException {
+    	ManifestMetadataParser parser = new ManifestMetadataParser();
+    	parser.parse(dict);
+    	// Create the components Factory according to the declared component
+        Element[] componentsMetadata = parser.getComponentsMetadata();
+        for (int i = 0; i < componentsMetadata.length; i++) {
+        	Activator.getLogger().log(Level.INFO, "[Bundle" + m_bundleContext.getBundle().getBundleId() + "] Create a component factory for " + componentsMetadata[i].getAttribute("classname"));
+        	addComponentFactory(componentsMetadata[i]);
+        }
+    }
+
+    /**
+     * Start the management : Manipulate the classes and start the component manager.
+     */
+    private void start() {
+        for (int i = 0; i < m_factories.length; i++) {
+            ComponentManagerFactory factory = m_factories[i];
+            factory.start(); // Start the management
+        }
+    }
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Callback.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Callback.java
new file mode 100644
index 0000000..5f93351
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Callback.java
@@ -0,0 +1,119 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.logging.Level;
+
+
+
+/**
+ * A callback allows calling a method on the component.
+ * @author Clement Escoffier
+ */
+public class Callback {
+
+	/**
+	 * Name of the method to call.
+	 */
+	private String m_method;
+
+	/**
+	 * Is the method a static method ?
+	 */
+	private boolean m_isStatic;
+
+	/**
+	 * Reference on the component manager.
+	 */
+	private ComponentManager m_manager;
+
+	 /**
+     * LifecycleCallback constructor.
+     * @param method : the name of the method to call
+     * @param isStatic : is the method a static method
+     * @param cm : the component manager of the component containing the method
+     */
+    public Callback(String method, boolean isStatic, ComponentManager cm) {
+        m_method = method;
+        m_isStatic = isStatic;
+        m_manager = cm;
+    }
+
+    /**
+     * Call the method.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    public void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Call an callback method : " + m_method);
+        Method method = m_manager.getClazz().getMethod(m_method, new Class[] {});
+        method.setAccessible(true);
+
+        if (m_isStatic) { method.invoke(null, new Object[]{}); }
+        else {
+        	// Two cases :
+        	// - if instances already exists : call on each instances
+        	// - if no instance exists : create an instance
+        	if (m_manager.getInstances().length == 0) {
+        		Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Create the first instance " + m_manager.getInstance());
+        		method.invoke(m_manager.getInstance(), new Object[]{});
+        	} else {
+        		for (int i = 0; i < m_manager.getInstances().length; i++) {
+            		Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Call the callback on the instance " + m_manager.getInstances()[i]);
+        			method.invoke(m_manager.getInstances()[i], new Object[]{});
+        		}
+        	}
+        }
+    }
+
+    /**
+     * Call the callback on the method with the argument given in parameter.
+     * @param arg : the parameters
+     * @throws NoSuchMethodException : the callback method is not found
+     * @throws IllegalAccessException : the callbback method cannot be called
+     * @throws InvocationTargetException : an error occurs inside the called method
+     */
+    public void call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Call an callback method : " + m_method);
+
+    	// Build an array of call for arg :
+    	Class[] classes = new Class[arg.length];
+    	for (int i = 0; i < arg.length; i++) {
+    		classes[i] = arg[i].getClass();
+    	}
+        Method method = m_manager.getClazz().getMethod(m_method, classes);
+        method.setAccessible(true);
+
+        if (m_isStatic) { method.invoke(null, arg); }
+        else {
+        	// Two cases :
+        	// - if instances already exists : call on each instances
+        	// - if no instance exists : create an instance
+        	if (m_manager.getInstances().length == 0) {
+        		Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Create the first instance " + m_manager.getInstance());
+        		method.invoke(m_manager.getInstance(), new Object[]{});
+        	} else {
+        		for (int i = 0; i < m_manager.getInstances().length; i++) {
+        			method.invoke(m_manager.getInstances()[i], arg);
+        		}
+        	}
+        }
+    }
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java
new file mode 100644
index 0000000..6d2eb6f
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java
@@ -0,0 +1,502 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The component manager class manage one "version" of a component.
+ * It manages component lifecycle, component instance creation and handlers.
+ * @author Clement Escoffier
+ */
+public class ComponentManager {
+
+	// STATIC PART
+
+	/**
+     * Component State : INVALID.
+     * The component is invalid when it start or when a component dependency is unvalid.
+     */
+    public static final int INVALID = 1;
+
+    /**
+     * Component State : VALID.
+     * The component is resolved when it is running and all its component dependencies are valid.
+     */
+    public static final int VALID = 2;
+
+    // END STATIC PART
+
+	/**
+	 * Parent factory (ComponentManagerFactory).
+	 */
+	private ComponentManagerFactory m_factory;
+
+	/**
+	 * Attached metadata of the managed component.
+	 */
+	private ComponentMetadata m_metadata;
+
+	/**
+	 * The context of the component.
+	 */
+	private BundleContext m_context;
+
+	/**
+	 * Handler list.
+	 */
+	private Handler[] m_handlers = new Handler[0];
+
+	/**
+	 * Component state (STOPPED at the beginning).
+	 */
+	private int m_state = INVALID;
+
+	// Fields use for the manipulation, the loading of the class and for the instance creation
+
+	/**
+	 * Manipulatd clazz.
+	 */
+	private Class m_clazz;
+
+	/**
+	 * Instances of the components.
+	 */
+	private Object[] m_instances = new Object[0];
+
+    // Constructor
+    /**
+     * Construct a new Component Manager.
+     * @param factory : the factory managing the component manager
+     */
+    public ComponentManager(ComponentManagerFactory factory) {
+    	m_factory = factory;
+    	m_context = factory.getBundleContext();
+    	Activator.getLogger().log(Level.INFO, "[Bundle " + m_context.getBundle().getBundleId() + "] Create a component manager from the factory " + m_factory);
+    }
+
+	/**
+	 * Configure the component manager.
+	 * Stop the existings handler, clear the handler list, change the metadata, recreate the handlers
+	 * @param cm
+	 */
+	public void configure(Element cm) {
+		Activator.getLogger().log(Level.INFO, "[Bundle " + m_context.getBundle().getBundleId() + "] Configure the component manager " + cm.getAttribute("className"));
+
+		// Stop all previous registred handler
+		if (m_handlers.length != 0) { stop(); }
+
+		// Clear the handler list
+		m_handlers = new Handler[0];
+
+		// Change the metadata
+		m_metadata = new ComponentMetadata(cm);
+
+		// Create the standard handlers and add these handlers to the list
+		for (int i = 0; i < IPojoConfiguration.INTERNAL_HANDLERS.length; i++) {
+			// Create a new instance
+			try {
+				Handler h = (Handler)IPojoConfiguration.INTERNAL_HANDLERS[i].newInstance();
+				h.configure(this, cm);
+			} catch (InstantiationException e) {
+				Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
+			} catch (IllegalAccessException e) {
+				Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] 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("")) {
+				Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Look for class for the namespace : " + cm.getNamespaces()[i]);
+				// It is not an internal handler, try to load it
+				try {
+					Class c = m_context.getBundle().loadClass(cm.getNamespaces()[i]);
+					//Class c = Class.forName(cm.getNamespaces()[i]);
+					Handler h = (Handler) c.newInstance();
+					h.configure(this, cm);
+				} catch (ClassNotFoundException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
+				} catch (InstantiationException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
+				} catch (IllegalAccessException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
+				}
+
+			}
+		}
+	}
+
+	/**
+	 * @return the component metadata.
+	 */
+	public ComponentMetadata getComponentMetatada() { return m_metadata; }
+
+	/**
+	 * @return the list of the registred handlers.
+	 */
+	public Handler[] getRegistredHandlers() { 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 Handler getHandler(String name) {
+		for (int i = 0; i < m_handlers.length; i++) {
+			if (m_handlers[i].getClass().getName().equalsIgnoreCase(name)) { return m_handlers[i]; }
+		}
+		return null;
+	}
+
+	// ===================== Lifecycle management =====================
+
+	/**
+	 * Start the component manager.
+	 */
+	public void start() {
+		// Start all the handlers
+		Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Start the component manager with " + m_handlers.length + " handlers");
+
+		// The new state of the component is UNRESOLVED
+		m_state = INVALID;
+
+		for (int i = 0; i < m_handlers.length; i++) {
+			m_handlers[i].start();
+		}
+
+		// Defines the state of the component :
+		check();
+	}
+
+	/**
+	 * Stop the component manager.
+	 */
+	public void stop() {
+		setState(INVALID);
+		// Stop all the handlers
+		for (int i = 0; i < m_handlers.length; i++) {
+			m_handlers[i].stop();
+		}
+		m_instances = new Object[0];
+	}
+
+	/**
+	 * 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) { Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Component " + m_metadata.getClassName() + " State -> UNRESOLVED"); }
+			if (state == VALID) { Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Component " + m_metadata.getClassName() + " State -> VALID"); }
+
+			// The state changed call the handler stateChange method
+			m_state = state;
+			for (int i = 0; i < m_handlers.length; i++) {
+				m_handlers[i].stateChanged(state);
+			}
+		}
+	}
+
+	/**
+	 * @return the actual state of the component
+	 */
+	public int getState() {
+		return m_state;
+	}
+
+	// ===================== end Lifecycle management =====================
+
+	// ================== Class & Instance management ===================
+
+	/**
+	 * @return the factory of the component
+	 */
+	public ComponentManagerFactory getFactory() { return m_factory; }
+
+	/**
+	 * Load the manipulated class.
+	 */
+	private void load() {
+        try {
+        	m_clazz = m_factory.getBundleContext().getBundle().loadClass(m_metadata.getClassName());
+        } catch (Exception  e) {
+            Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] Class not found during the loading phase : " + e.getMessage());
+            return;
+        }
+	}
+
+	/**
+	 * @return true if the class is loaded
+	 */
+	private boolean isLoaded() {
+		return (m_clazz != null);
+	}
+
+	private void addInstance(Object o) {
+        for (int i = 0; (m_instances != null) && (i < m_instances.length); i++) {
+            if (m_instances[i] == o) { return; }
+        }
+
+        if (m_instances.length > 0) {
+            Object[] newInstances = new Object[m_instances.length + 1];
+            System.arraycopy(m_instances, 0, newInstances, 0, m_instances.length);
+            newInstances[m_instances.length] = o;
+            m_instances = newInstances;
+        }
+        else {
+        	m_instances = new Object[] {o};
+        }
+	}
+
+	private void removeInstance(Object o) {
+		int idx = -1;
+        for (int i = 0; i < m_instances.length; i++) {
+            if (m_instances[i] == o) { idx = i; break; }
+        }
+
+        if (idx >= 0) {
+            if ((m_instances.length - 1) == 0) { m_instances = new Element[0]; }
+            else {
+                Object[] newInstances = new Object[m_instances.length - 1];
+                System.arraycopy(m_instances, 0, newInstances, 0, idx);
+                if (idx < newInstances.length) {
+                    System.arraycopy(m_instances, idx + 1, newInstances, idx, newInstances.length - idx); }
+                m_instances = newInstances;
+            }
+        }
+	}
+
+	/**
+	 * @return the created instance of the component.
+	 */
+	public Object[] getInstances() { return m_instances; }
+
+	/**
+	 * Delete the created instance (remove it from the list, to allow the garbage collector to eat the instance).
+	 * @param o : the instance to delete
+	 */
+	public void deleteInstance(Object o) { removeInstance(o); }
+
+	/**
+	 * Create an instance of the component.
+	 * This method need to be called one time only for singleton provided service
+	 * @return a new instance
+	 */
+	public Object createInstance() {
+		if (!isLoaded()) { load(); }
+		Object instance = null;
+		try {
+
+			Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> call setComponentManager");
+			// Invoke the static method setComponentManager on the manipulated class
+			Method method = m_clazz.getMethod("setComponentManager", new Class[] {this.getClass()});
+			method.invoke(null, new Object[] {this});
+
+			Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> Try to find the constructor");
+
+			// Try to find if there is a constructor with a bundle context as parameter :
+			try {
+				Constructor constructor = m_clazz.getConstructor(new Class[] {BundleContext.class});
+				constructor.setAccessible(true);
+				instance = constructor.newInstance(new Object[] {m_factory.getBundleContext()});
+			}
+			catch (NoSuchMethodException e) {
+				Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> No constructor with a bundle context");
+			}
+
+			// Create an instance if no instance are already created with <init>()BundleContext
+			Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> Try to create the object with an empty constructor");
+			if (instance == null) { instance = m_clazz.newInstance(); }
+
+		} catch (InstantiationException e) {
+			Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> The Component Instance cannot be instancied : " + e.getMessage());
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> The Component Instance is not accessible : " + e.getMessage());
+			e.printStackTrace();
+		} catch (SecurityException e) {
+			Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> The Component Instance is not accessible (security reason) : " + e.getMessage());
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> Cannot invoke the setComponentManager method (illegal argument) : " + e.getMessage());
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> Cannot invoke the setComponentManager method (illegal target) : " + e.getMessage());
+			e.printStackTrace();
+		} catch (NoSuchMethodException e) {
+			Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> Cannot invoke the setComponentManager method (method not found) : " + e.getMessage());
+			e.printStackTrace();
+		}
+
+		Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> Return the instance " + instance);
+
+		// Register the new instance
+		addInstance(instance);
+		return instance;
+	}
+
+	/**
+	 * @return the instance of the component to use for singleton component
+	 */
+	public Object getInstance() {
+		if (m_instances.length == 0) { createInstance(); }
+		return m_instances[0];
+	}
+
+	/**
+	 * @return the manipulated class
+	 */
+	public Class getClazz() {
+		if (!isLoaded()) { load(); }
+		return m_clazz;
+	}
+
+	//	================== end Class & Instance management ================
+
+	//  ======================== Handlers Management ======================
+
+	/**
+     * Register the given handler to the current component manager.
+	 * @param h : the handler to register
+	 */
+	public void register(Handler h) {
+        for (int i = 0; (m_handlers != null) && (i < m_handlers.length); i++) {
+            if (m_handlers[i] == h) {
+                return;
+            }
+        }
+
+        if (m_handlers != null) {
+            Handler[] newList = new Handler[m_handlers.length + 1];
+            System.arraycopy(m_handlers, 0, newList, 0, m_handlers.length);
+            newList[m_handlers.length] = h;
+            m_handlers = newList;
+        }
+	}
+
+	/**
+     * Unregister the given handler.
+	 * @param h : the handler to unregiter
+	 */
+	public void unregister(Handler h) {
+        int idx = -1;
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i] == h) {
+                idx = i;
+                break;
+            }
+        }
+
+        if (idx >= 0) {
+            if ((m_handlers.length - 1) == 0) {
+                m_handlers = new Handler[0];
+            }
+            else {
+                Handler[] newList = new Handler[m_handlers.length - 1];
+                System.arraycopy(m_handlers, 0, newList, 0, idx);
+                if (idx < newList.length)             {
+                    System.arraycopy(
+                            m_handlers, idx + 1, newList, idx, newList.length - idx);
+                }
+                m_handlers = newList;
+            }
+        }
+	}
+
+	/**
+	 * This method is called by the manipulated class each time that a GETFIELD instruction is found.
+	 * The method ask to each handler which value need to be returned.
+	 * @param fieldName : the field name on which the GETFIELD instruction is called
+	 * @param initialValue : the value of the field in the code
+	 * @return the value decided by the last asked handler (throw a warining if two fields decide two different values)
+	 */
+	public Object getterCallback(String fieldName, Object initialValue) {
+		Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Call the getterCallbackMethod on " + fieldName +  " with " + initialValue);
+		Object result = null;
+		for (int i = 0; i < m_handlers.length; i++) {
+			Object handlerResult = m_handlers[i].getterCallback(fieldName, initialValue);
+			if (handlerResult != initialValue) { result = handlerResult; }
+		}
+
+		if (result != null) {
+			Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] getterCallbackMethod return for " + fieldName +  " -> " + result);
+			return result;
+		} else {
+			Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] getterCallbackMethod return for " + fieldName +  " -> " + initialValue);
+			return initialValue;
+		}
+	}
+
+	/**
+	 * This method is called by the manipulated class each time that a PUTFILED instruction is found.
+	 * the method send to each handler the new value.
+	 * @param fieldName : the field name on which the PUTFIELD instruction is called
+	 * @param objectValue : the value of the field
+	 */
+	public void setterCallback(String fieldName, Object objectValue) {
+		Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Call the setterCallbackMethod on " + fieldName +  " with " + objectValue);
+
+		for (int i = 0; i < m_handlers.length; i++) {
+			m_handlers[i].setterCallback(fieldName, objectValue);
+		}
+	}
+
+	/**
+	 * @return the context of the component.
+	 */
+	public BundleContext getContext() { return m_context; }
+
+	/**
+	 * Check the state of all handlers.
+	 */
+	public void check() {
+		Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Check the component state");
+		boolean isValid = true;
+		for (int i = 0; i < m_handlers.length; i++) {
+			boolean b = m_handlers[i].isValid();
+			Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Validity of the handler : " + m_handlers[i] + " = " + b);
+			isValid = isValid && b;
+		}
+
+		// Update the component state if necessary
+		if (!isValid && m_state == VALID) {
+			// Need to update the state to UNRESOLVED
+			setState(INVALID);
+			m_instances = new Object[0];
+			return;
+		}
+		if (isValid && m_state == INVALID) {
+			setState(VALID);
+			if (m_metadata.isImmediate() && m_instances.length == 0) { createInstance(); }
+		}
+
+		Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] Component Manager : " + m_state);
+	}
+
+
+	// ======================= end Handlers Management =====================
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManagerFactory.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManagerFactory.java
new file mode 100644
index 0000000..92678da
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManagerFactory.java
@@ -0,0 +1,159 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.logging.Level;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The component manager factory class manages component manager object.
+ * @author Clement Escoffier
+ */
+public class ComponentManagerFactory {
+
+	// Fields :
+	/**
+	 * List of the managed component manager.
+	 */
+	private ComponentManager[] m_componentManagers = new ComponentManager[0];
+
+	/**
+	 * The bundle context reference.
+	 */
+	private BundleContext m_bundleContext = null;
+
+	//End field
+
+	// Field accessors
+
+	 /**
+     * Add a component manager factory to the component manager list.
+     * @param cm : the new component metadata.
+     */
+    private void addComponent(ComponentManager cm) {
+
+    	// If the component manager array is not empty add the new factory at the end
+        if (m_componentManagers.length != 0) {
+        	ComponentManager[] newCM = new ComponentManager[m_componentManagers.length + 1];
+            System.arraycopy(m_componentManagers, 0, newCM, 0, m_componentManagers.length);
+            newCM[m_componentManagers.length] = cm;
+            m_componentManagers = newCM;
+        }
+        // Else create an array of size one with the new component manager
+        else {
+            m_componentManagers = new ComponentManager[] {cm};
+        }
+    }
+
+    /**
+     * Remove the component manager for m the list.
+     * @param cm : the component manager to remove
+     */
+    public void removeComponent(ComponentManager cm) {
+    	cm.stop();
+    	int idx = -1;
+
+    	for (int i = 0; i < m_componentManagers.length; i++) {
+    		if (m_componentManagers[i] == cm) { idx = i; }
+    	}
+
+        if (idx >= 0) {
+            if ((m_componentManagers.length - 1) == 0) { m_componentManagers = new ComponentManager[0]; }
+            else {
+            	ComponentManager[] newCMList = new ComponentManager[m_componentManagers.length - 1];
+                System.arraycopy(m_componentManagers, 0, newCMList, 0, idx);
+                if (idx < newCMList.length) {
+                    System.arraycopy(m_componentManagers, idx + 1, newCMList, idx, newCMList.length - idx); }
+                m_componentManagers = newCMList;
+            }
+            }
+       }
+
+    /**
+     * @return the iPOJO activator reference
+     */
+    public BundleContext getBundleContext() { return m_bundleContext; }
+
+	// End field accessors
+
+	/**
+	 * Constructor of a ComponentManagerFactory from a component metadata.
+	 * This contructor is use when the iPOJO Activator is used.
+	 * @param cm : Component Metadata for the component factory
+	 */
+	protected ComponentManagerFactory(Activator activator, Element cm) {
+		m_bundleContext = activator.getBundleContext();
+		createComponentManager(cm);
+	}
+
+	/**
+	 * Create a component manager factory and create a component manager with the given medatada.
+	 * @param bc : bundle context
+	 * @param cm : metadata of the component to create
+	 */
+	public ComponentManagerFactory(BundleContext bc, Element cm) {
+		m_bundleContext = bc;
+		createComponentManager(cm);
+	}
+
+	/**
+	 * Create a component manager factory, no component manager are created.
+	 * @param bc
+	 */
+	public ComponentManagerFactory(BundleContext bc) {
+		m_bundleContext = bc;
+	}
+
+	/**
+	 * Create a component manager form the component metadata.
+	 * @param cm : Component Metadata
+	 * @return a component manager configured with the metadata
+	 */
+	public ComponentManager createComponentManager(Element cm) {
+		ComponentManager component = new ComponentManager(this);
+		component.configure(cm);
+		addComponent(component);
+		return component;
+	}
+
+	// Factory lifecycle management
+
+	/**
+	 * Stop all the component managers.
+	 */
+	public void stop() {
+		Activator.getLogger().log(Level.INFO, "[Bundle " + m_bundleContext.getBundle().getBundleId() + "] Stop the component factory");
+		for (int i = 0; i < m_componentManagers.length; i++) {
+			ComponentManager cm = m_componentManagers[i];
+			cm.stop();
+		}
+	}
+
+	/**
+	 * Start all the component managers.
+	 */
+	public void start() {
+		Activator.getLogger().log(Level.INFO, "[Bundle " + m_bundleContext.getBundle().getBundleId() + "] Start the component factory");
+		for (int i = 0; i < m_componentManagers.length; i++) {
+			ComponentManager cm = m_componentManagers[i];
+			cm.start();
+		}
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentMetadata.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentMetadata.java
new file mode 100644
index 0000000..662b170
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentMetadata.java
@@ -0,0 +1,73 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.logging.Level;
+
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Component Metadata.
+ * @author Clement Escoffier
+ */
+public class ComponentMetadata {
+
+	/**
+	 * Class name of the component.
+	 */
+	private String m_className;
+
+	/**
+	 * Is the component an immediate component ?
+	 */
+	private boolean m_isImmediate = false;
+
+    /**
+	 * Metadata of the component.
+	 */
+	private Element m_metadata;
+
+	/**
+     * Constructor.
+	 * @param metadata : metadata of the component
+	 */
+	public ComponentMetadata(Element metadata) {
+		m_metadata = metadata;
+		m_className = metadata.getAttribute("className");
+		if (m_className == null) {
+			Activator.getLogger().log(Level.SEVERE, "The class name of ths component cannot be setted, it does not exist in the metadata");
+		}
+		if (metadata.containsAttribute("immediate") && metadata.getAttribute("immediate").equals("true")) { m_isImmediate = true; }
+	}
+
+	// Getter
+	/**
+	 * @return the class name
+	 */
+	public String getClassName() { return m_className; }
+
+	/**
+	 * @return the component metadata
+	 */
+	public Element getMetadata() { return m_metadata; }
+
+	/**
+	 * @return true if its an immediate component
+	 */
+	public boolean isImmediate() { return m_isImmediate; }
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/DummyActivator.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/DummyActivator.java
new file mode 100644
index 0000000..87a3b74
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/DummyActivator.java
@@ -0,0 +1,43 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This class is just if you start ipojo. It does nothing but avoid the launch of the Activator class on the iPOJO bundle
+ * @author escoffie
+ *
+ */
+public class DummyActivator implements BundleActivator {
+
+	/**
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext arg0) throws Exception {
+		System.out.println("iPOJO Started");
+	}
+
+	/**
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext arg0) throws Exception {
+		System.out.println("iPOJO Stopped");
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Handler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Handler.java
new file mode 100644
index 0000000..f08c9d0
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Handler.java
@@ -0,0 +1,72 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo;
+
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Handler Interface.
+ * An handler need implements tese method to be notifed of lifecycle change, getfield operation and putfield operation
+ * @author Clement Escoffier
+ */
+public interface Handler {
+
+	/**
+	 * Configure the handler.
+	 * @param cm : the component manager
+	 * @param metadata : the metadata of the component
+	 */
+	void configure(ComponentManager cm, Element metadata);
+
+	/**
+	 * Stop the handler : stop the management.
+	 */
+	void stop();
+
+	/**
+	 * Start the handler : start the management.
+	 */
+	void start();
+
+	/**
+	 * This method is called when a PUTFIELD operation is detected.
+	 * @param fieldName : the field name
+	 * @param value : the value passed to the field
+	 */
+	void setterCallback(String fieldName, Object value);
+
+	/**
+	 * This method is called when a GETFIELD operation is detected.
+	 * @param fieldName : the field name
+	 * @param value : the value passed to the field (by the previous handler)
+	 * @return : the managed value of the field
+	 */
+	Object getterCallback(String fieldName, Object value);
+
+	/**
+	 * Is the actual state valid for this handler ?
+	 * @return true is the state seems valid for the handler
+	 */
+	boolean isValid();
+
+	/**
+	 * This method is called when the component state changed.
+	 * @param state : the new state
+	 */
+	void stateChanged(int state);
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
new file mode 100644
index 0000000..13aaff3
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
@@ -0,0 +1,51 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.logging.Level;
+
+import org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler;
+import org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler;
+import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
+import org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler;
+import org.apache.felix.ipojo.handlers.providedService.ProvidedServiceHandler;
+
+/**
+ * Activator Basic Configuration.
+ * - Log Level
+ * - Available handlers
+ * @author Clement Escoffier
+ */
+public class IPojoConfiguration {
+
+	/**
+	 * iPOJO logger log level.
+	 */
+	public static final Level LOG_LEVEL = Level.WARNING;
+
+	/**
+	 * Available handlers in the iPOJO bundle.
+	 */
+	public static final Class[] INTERNAL_HANDLERS = new Class[] {
+		DependencyHandler.class,
+		ProvidedServiceHandler.class,
+		LifecycleCallbackHandler.class,
+		ConfigurationHandler.class,
+		ArchitectureHandler.class
+	};
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Nullable.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Nullable.java
new file mode 100644
index 0000000..6287128
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Nullable.java
@@ -0,0 +1,25 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo;
+
+/**
+ * A nullable object must implement this interface.
+ * @author Clement Escoffier
+ */
+public interface Nullable {
+    // Nothing
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java
new file mode 100644
index 0000000..22f4f15
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java
@@ -0,0 +1,32 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.architecture;
+
+/**
+ * Architecture service.
+ * Allows to have information of the service delivery about GenSD component.
+ * @author Clement Escoffier
+ */
+public interface Architecture {
+
+    /**
+     * Return the full architecture.
+     * @return : the current component description
+     */
+    ComponentDescription getComponentDescription();
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
new file mode 100644
index 0000000..01eccdb
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
@@ -0,0 +1,150 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.architecture;
+
+import java.util.HashMap;
+
+
+/**
+ * Component Description.
+ * @author Clement Escoffier
+ */
+public class ComponentDescription {
+
+    /**
+     * The Component class name.
+     * This String is the identifier of the component.
+     */
+    private String m_className;
+
+    /**
+     * List of provided service.
+     */
+    private ProvidedServiceDescription[] m_provideServices = new ProvidedServiceDescription[0];
+
+    /**
+     * List of dependencies.
+     */
+    private DependencyDescription[] m_dependencies = new DependencyDescription[0];
+
+    /**
+     * Hashmap [Instance reference, service reference] of the used service.
+     */
+    private HashMap m_usedServices = new HashMap();
+
+    /**
+     * Created Instances of the components.
+     */
+    private String[] m_instances = new String[0];
+
+    /**
+     * State of the component (VALID / UNRESOLVED).
+     */
+    private int m_state;
+
+    /**
+     * Constructor.
+     * @param name : the name of the component (the class name).
+     * @param state : the state of the component.
+     */
+    public ComponentDescription(String name, int state) {
+        m_className = name;
+        m_state = state;
+        m_usedServices.clear();
+        m_instances = new String[0];
+    }
+
+    /**
+     * @return the created instances
+     */
+    public String[] getInstances() { return m_instances; }
+
+    /**
+     * Set the instances array.
+     */
+    public void setInstances(String[] instances) { m_instances = instances; }
+
+    /**
+     * @return : the class name of the component
+     */
+    public String getClassName() { return m_className; }
+
+    /**
+     * @return the live dependency list
+     */
+    public DependencyDescription[] getDependencies() { return m_dependencies; }
+
+    /**
+     * @return the live provided service list
+     */
+    public ProvidedServiceDescription[] getProvideServices() { return m_provideServices; }
+
+    /**
+     * Add a dependency.
+     * @param dep : the dependency to add
+     */
+    public void addDependency(DependencyDescription dep) {
+        // Verify that the dependency description is not already in the array.
+        for (int i = 0; (i < m_dependencies.length); i++) {
+            if (m_dependencies[i] == dep) {
+                return; //NOTHING TO DO, the description is already in the array
+            }
+        }
+            // The component Description is not in the array, add it
+            DependencyDescription[] newDep = new DependencyDescription[m_dependencies.length + 1];
+            System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
+            newDep[m_dependencies.length] = dep;
+            m_dependencies = newDep;
+    }
+
+    /**
+     * Add a provided service.
+     * @param pds : the provided service to add
+     */
+    public void addProvidedService(ProvidedServiceDescription pds) {
+        //Verify that the provided service description is not already in the array.
+        for (int i = 0; (i < m_provideServices.length); i++) {
+            if (m_provideServices[i] == pds) {
+                return; //NOTHING DO DO, the description is already in the array
+            }
+        }
+
+            // The component Description is not in the array, add it
+            ProvidedServiceDescription[] newPSD = new ProvidedServiceDescription[m_provideServices.length + 1];
+            System.arraycopy(m_provideServices, 0, newPSD, 0, m_provideServices.length);
+            newPSD[m_provideServices.length] = pds;
+            m_provideServices = newPSD;
+
+    }
+
+    /**
+     * Set the state of the component.
+     * @param i : the state
+     */
+    public void setState(int i) {
+        m_state = i;
+    }
+
+    /**
+     * @return the state of the component.
+     */
+    public int getState() {
+        return m_state;
+    }
+
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/DependencyDescription.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/DependencyDescription.java
new file mode 100644
index 0000000..3559d9a
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/DependencyDescription.java
@@ -0,0 +1,169 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.architecture;
+
+import java.util.HashMap;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Dependency Description.
+ * @author Clement Escoffier
+ */
+public class DependencyDescription {
+
+    /**
+     * Needed Service Interface.
+     */
+    private String m_interface;
+
+    /**
+     * Multiple ?
+     */
+    private boolean m_multiple;
+
+    /**
+     * Optional ?
+     */
+    private boolean m_optional;
+
+    /**
+     * State (VALID | INVALID).
+     */
+    private int m_state;
+
+    /**
+     * Filter.
+     */
+    private String m_filter;
+    /**
+     * Hashmap [Instance reference, service reference] of the used service.
+     */
+    private HashMap m_usedServices = new HashMap();
+
+
+    /**
+     * The list of service reference.
+     */
+    private ServiceReference[] m_serviceReferences;
+
+    /**
+     * Parent of the dependency either de ProvidedServiceDescription or a ComponentDescription.
+     */
+    private Object m_parent;
+
+
+    /**
+     * @return true if the dependency is a multiple dependency.
+     */
+    public boolean isMultiple() {
+        return m_multiple;
+    }
+
+    /**
+     * @return true if the dependency is an optional dependency.
+     */
+    public boolean isOptional() {
+        return m_optional;
+    }
+
+    /**
+     * @return the filter.
+     */
+    public String getFilter() {
+        return m_filter;
+    }
+
+    /**
+     * @return the needed interface.
+     */
+    public String getInterface() {
+        return m_interface;
+    }
+
+    /**
+     * @return the state of the dependency.
+     */
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * Constructor.
+     * @param itf : the needed itf
+     * @param multiple : is the dependency a multiple dependency ?
+     * @param optional : is the depdendency optional ?
+     * @param filter : the filter
+     * @param state : the state
+     * @param parent : the description of the parent (either a ProvidedServiceDescription, either a ComponentDescription)
+     */
+    public DependencyDescription(String itf, boolean multiple, boolean optional, String filter, int state, Object parent) {
+        super();
+        m_interface = itf;
+        m_multiple = multiple;
+        m_optional = optional;
+        m_filter = filter;
+        m_state = state;
+        m_serviceReferences = new ServiceReference[0];
+        m_parent = parent;
+    }
+
+    /**
+     * @return the array of service reference (only if the cardinality could be n).
+     */
+    public ServiceReference[] getServiceReferences() {
+        return m_serviceReferences;
+    }
+
+    /**
+     * @return the ServiceReference (only if the cardinality could be 1).
+     */
+    public ServiceReference getServiceReference() {
+        return m_serviceReferences[0];
+    }
+
+    /**
+     * Set the service reference array.
+     * @param sr : the array of service reference
+     */
+    public void setServiceReferences(ServiceReference[] sr) {
+        m_serviceReferences = sr;
+    }
+
+    /**
+     * @return the parent of the dependency
+     */
+    public Object getParent() {
+        return m_parent;
+    }
+
+    /**
+     * @return the hashmap [object reference, service reference] containing the used services
+     */
+    public HashMap getUsedServices() { return m_usedServices; }
+
+    /**
+     * Set the usedServices.
+     * @param hm : the new usedService
+     */
+    public void setUsedServices(HashMap hm) {
+    	m_usedServices = hm;
+    }
+
+
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/ProvidedServiceDescription.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/ProvidedServiceDescription.java
new file mode 100644
index 0000000..64311ba
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/ProvidedServiceDescription.java
@@ -0,0 +1,153 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.architecture;
+
+import java.util.Properties;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Provided Service Description.
+ * @author Clement Escoffier
+ */
+public class ProvidedServiceDescription {
+
+    /**
+     * Provided Service Specification.
+     */
+    private String[] m_serviceSpecification;
+
+    /**
+     * Dependency of the service.
+     */
+    private DependencyDescription[] m_dependencies = new DependencyDescription[0];
+
+
+    /**
+     * State.
+     */
+    private int m_state;
+
+    /**
+     * The service reference.
+     */
+    private ServiceReference m_serviceReference;
+
+
+    /**
+     * Handler on the component description who contains this description.
+     */
+    private ComponentDescription m_parent;
+
+    /**
+     * Properties of the provided service.
+     */
+    private Properties m_properties = new Properties();
+
+
+    /**
+     * Constructor.
+     * @param serviceSpecification : the provided contract
+     * @param state : state (UNREGITRED | REGISTRED)
+     * @param sr : Service Registration (to obtain the reference), or null if state is UNREGISTRED
+     * @param parent : the component description declaring this proided service
+     */
+    public ProvidedServiceDescription(String[] serviceSpecification, int state, ServiceReference sr, ComponentDescription parent) {
+        m_serviceSpecification = serviceSpecification;
+        m_state = state;
+        m_serviceReference = sr;
+        m_parent = parent;
+    }
+
+    /**
+     * @return the provided contract name.
+     */
+    public String[] getServiceSpecification() {
+        return m_serviceSpecification;
+    }
+
+    /**
+     * Add a dependency descriptino to this provided service description.
+     * @param dep : the dependency description to add
+     */
+    public void addDependency(DependencyDescription dep) {
+        // Verify that the dependency description is not already in the array.
+        for (int i = 0; (i < m_dependencies.length); i++) {
+            if (m_dependencies[i] == dep) {
+                return; //NOTHING DO DO, the description is already in the array
+            }
+        }
+            // The component Description is not in the array, add it
+            DependencyDescription[] newDep = new DependencyDescription[m_dependencies.length + 1];
+            System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
+            newDep[m_dependencies.length] = dep;
+            m_dependencies = newDep;
+    }
+
+    /**
+     * Add a property to the current provided service description.
+     * @param key : the key of the property
+     * @param value : the value of the property
+     */
+    public void addProperty(String key, String value) {
+        m_properties.put(key, value);
+    }
+
+    /**
+     * Set the set of properties. This function create a clone of the argument.
+     * @param props : the properties
+     */
+    public void setProperty(Properties props) {
+        m_properties = (Properties)props.clone();
+    }
+
+    /**
+     * @return the dependeny description list.
+     */
+    public DependencyDescription[] getDependencies() {
+        return m_dependencies;
+    }
+
+    /**
+     * @return the properties.
+     */
+    public Properties getProperties() {
+        return m_properties;
+    }
+
+    /**
+     * @return the state of the provided service (UNREGISTRED | REGISTRED).
+     */
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * @return the service reference (null if the service is unregistred).
+     */
+    public ServiceReference getServiceReference() {
+        return m_serviceReference;
+    }
+
+    /**
+     * @return the parent description.
+     */
+    public ComponentDescription getComponentDescription() {
+        return m_parent;
+    }
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/State.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/State.java
new file mode 100644
index 0000000..1291f03
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/architecture/State.java
@@ -0,0 +1,77 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.architecture;
+
+/**
+ * @author Clement Escoffier
+ *
+ */
+public class State {
+
+    /**
+     * Return the String corresponding to a component state.
+     * @param state : the state in int
+     * @return : the string of the state (Stopped, Unresolved, Resolved) or "Unknow" if state is not revelant
+     */
+    public static String printComponentState(int state) {
+        switch(state) {
+        case(0) :
+            return "STOPPED";
+        case(1) :
+            return "INVALID";
+        case(2) :
+            return  "VALID";
+        default :
+            return "UNKNOW";
+        }
+    }
+
+    /**
+     * Return the String corresponding to a dependency state.
+     * @param state : the state in int
+     * @return : the string of the state (Stopped, Valid, Invalid) or "Unknow" if state is not revelant
+     */
+    public static String printDependencyState(int state) {
+        switch(state) {
+        case(0) :
+            return "STOPPED";
+        case(1) :
+            return "RESOLVED";
+        case(2) :
+            return  "UNRESOLVED";
+        default :
+            return "UNKNOW";
+        }
+    }
+
+    /**
+     * Return the String corresponding to a provided service state.
+     * @param state : the state in int
+     * @return : the string of the state (Unregistred, Registredu) or "Unknow" if state is not revelant
+     */
+    public static String printProvidedServiceState(int state) {
+        switch(state) {
+        case(0) :
+            return "UNREGISTRED";
+        case(1) :
+            return "REGISTRED";
+        default :
+            return "UNKNOW";
+        }
+    }
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
new file mode 100644
index 0000000..d17cde8
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
@@ -0,0 +1,177 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.architecture;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.DependencyDescription;
+import org.apache.felix.ipojo.architecture.ProvidedServiceDescription;
+import org.apache.felix.ipojo.handlers.dependency.Dependency;
+import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
+import org.apache.felix.ipojo.handlers.dependency.DependencyMetadata;
+import org.apache.felix.ipojo.handlers.providedService.Property;
+import org.apache.felix.ipojo.handlers.providedService.PropertyMetadata;
+import org.apache.felix.ipojo.handlers.providedService.ProvidedService;
+import org.apache.felix.ipojo.handlers.providedService.ProvidedServiceHandler;
+import org.apache.felix.ipojo.handlers.providedService.ProvidedServiceMetadata;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Achtiecture Handler : do reflection on your component.
+ * @author Clement Escoffier
+ */
+public class ArchitectureHandler implements Handler, Architecture {
+
+	/**
+	 * Component Manager.
+	 */
+	private ComponentManager m_manager;
+
+    /**
+     * Service Registration of the Architecture service provided by this handler.
+     */
+    private ServiceRegistration m_sr;
+
+    /**
+     * Unique name of the component : either the name of the component, either the classname if the name if not setted.
+     */
+    private String m_name;
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+	 */
+	public void configure(ComponentManager cm, Element metadata) {
+		if (metadata.containsAttribute("architecture")) {
+			String isArchitectureEnabled = (metadata.getAttribute("architecture")).toLowerCase();
+			if (isArchitectureEnabled.equals("true")) { cm.register(this); }
+		}
+
+		if (metadata.containsAttribute("name")) { m_name = metadata.getAttribute("name"); }
+		else { m_name = metadata.getAttribute("className"); }
+
+		m_manager = cm;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stop()
+	 */
+	public void stop() {
+        try {
+            if (m_sr != null) { m_sr.unregister(); }
+        } 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 Implementation Class", m_manager.getComponentMetatada().getClassName());
+		properties.put(Constants.SERVICE_PID, m_name);
+
+		m_sr = bc.registerService(Architecture.class.getName(), this, properties);
+
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+	 */
+	public void setterCallback(String fieldName, Object value) { // Nothing to do
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+	 */
+	public Object getterCallback(String fieldName, Object value) { return value; }
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#isValid()
+	 */
+	public boolean isValid() { return true; }
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+	 */
+	public void stateChanged(int state) {
+		// Nothing to do
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.architecture.Architecture#getComponentDescription()
+	 */
+	public ComponentDescription getComponentDescription() {
+		int componentState = m_manager.getState();
+		ComponentDescription componentDescription = new ComponentDescription(m_name, componentState);
+
+		String[] instances = new String[m_manager.getInstances().length];
+		for (int i = 0; i < m_manager.getInstances().length; i++) {
+			instances[i] = m_manager.getInstances()[i].toString();
+		}
+		componentDescription.setInstances(instances);
+
+		Handler[] handlers = m_manager.getRegistredHandlers();
+		for (int i = 0; i < handlers.length; i++) {
+			if (handlers[i] instanceof DependencyHandler) {
+				DependencyHandler dh = (DependencyHandler)handlers[i];
+				for (int j = 0; j < dh.getDependencies().length; j++) {
+					Dependency dep = dh.getDependencies()[j];
+					DependencyMetadata dm = dep.getMetadata();
+
+					// Create & add the dependency description
+					DependencyDescription dd = new DependencyDescription(dm.getServiceSpecification(), dm.isMultiple(), dm.isOptional(), dm.getFilter(), dep.getState(), componentDescription);
+					dd.setUsedServices(dep.getUsedServices());
+					componentDescription.addDependency(dd);
+				}
+			}
+			if (handlers[i] instanceof ProvidedServiceHandler) {
+				ProvidedServiceHandler psh = (ProvidedServiceHandler)handlers[i];
+				for (int j = 0; j < psh.getProvidedService().length; j++) {
+					ProvidedService ps = psh.getProvidedService()[j];
+					ProvidedServiceMetadata psm = ps.getMetadata();
+					ProvidedServiceDescription psd = new ProvidedServiceDescription(psm.getServiceSpecification(), ps.getState(), ps.getServiceReference(), componentDescription);
+
+					Properties props = new Properties();
+					for (int k = 0; k < ps.getProperties().length; k++) {
+						Property prop = ps.getProperties()[k];
+						PropertyMetadata pm = prop.getMetadata();
+						if (prop.getValue() != null) {
+							props.put(pm.getName(), prop.getValue().toString());
+						}
+					}
+					psd.setProperty(props);
+					componentDescription.addProvidedService(psd);
+				}
+			}
+
+		}
+		return componentDescription;
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
new file mode 100644
index 0000000..8f5a636
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
@@ -0,0 +1,157 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.configuration;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * @author Clement Escoffier
+ * Configurable Property
+ */
+public class ConfigurableProperty {
+
+	/**
+	 * Name of the property (filed name if not set).
+	 */
+	private String m_name;
+
+	/**
+	 * Field of the property.
+	 */
+	private String m_field;
+
+	/**
+	 * Value of the property.
+	 */
+	private Object m_value;
+
+	/**
+	 * Configuration Handler managing this property.
+	 */
+	private ConfigurationHandler m_handler;
+
+	/**
+	 * Configurable Property Constructor.
+	 * @param name : name of the property (optional)
+	 * @param field : name of the field (mandatory)
+	 * @param value : initial value of the property (optional)
+	 * @param ch : configuration handler managing this configurable property
+	 */
+	public ConfigurableProperty(String name, String field, String value, ConfigurationHandler ch) {
+		m_handler = ch;
+		if (name != null) { m_name = name; }
+		else { m_name = field; }
+		m_field = field;
+
+		if (value != null) { setValue(m_field, value); }
+
+	}
+
+	/**
+     * Set the value of the property.
+     * @param strValue : value of the property (String)
+     */
+    private void setValue(String field, String strValue) {
+    	// Look for the type of the field
+    	Element manipulation = m_handler.getComponentManager().getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+    	String type = null;
+    	for (int i = 0; i < manipulation.getElements("Field").length; i++) {
+    		if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
+    			type = manipulation.getElements("Field")[i].getAttribute("type");
+    			break;
+    		}
+    	}
+
+    	if (type == null) { Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] The field " + field + " does not exist in the implementation"); return; }
+
+    	Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Set the value of the configurable property " + field + " [" + type + "] " + " with the value : " + strValue);
+
+    	Object value = null;
+
+        if (type.equals("string") || type.equals("String")) { value = new String(strValue); }
+        if (type.equals("boolean")) { value = new Boolean(strValue); }
+        if (type.equals("byte")) { value = new Byte(strValue); }
+        if (type.equals("short")) { value = new Short(strValue); }
+        if (type.equals("int")) { value = new Integer(strValue); }
+        if (type.equals("long")) { value = new Long(strValue); }
+        if (type.equals("float")) { value = new Float(strValue); }
+        if (type.equals("double")) { value = new Double(strValue); }
+
+        if (value == null) {
+        	// Else it is a neither a primitive type neither a String -> create the object by calling a constructor with a string in argument.
+        	try {
+        		Class c = m_handler.getComponentManager().getContext().getBundle().loadClass(type);
+        		Constructor cst = c.getConstructor(new Class[] {String.class});
+        		value = cst.newInstance(new Object[] {strValue});
+        	} catch (ClassNotFoundException e) {
+        		System.err.println("Class not found exception in setValue on " + type);
+        		e.printStackTrace();
+        		return;
+        	} catch (SecurityException e) {
+        		e.printStackTrace();
+        		return;
+        	} catch (NoSuchMethodException e) {
+        		System.err.println("Constructor not found exeption in setValue on " + type);
+        		e.printStackTrace();
+        		return;
+        	} catch (IllegalArgumentException e) {
+        		System.err.println("Argument problem to call the constructor of the type " + type);
+        		e.printStackTrace();
+        		return;
+        	} catch (InstantiationException e) {
+        		System.err.println("Instantiation problem  " + type);
+        		e.printStackTrace();
+        		return;
+        	} catch (IllegalAccessException e) {
+        		e.printStackTrace();
+        	} catch (InvocationTargetException e) {
+        		System.err.println("Invocation problem " + type);
+        		e.printStackTrace();
+        		return;
+        	}
+        }
+
+        m_value = value;
+
+    }
+
+    /**
+     * @return the name of the property.
+     */
+    public String getName() { return m_name; }
+
+    /**
+     * @return the field of the property.
+     */
+    public String getField() { return m_field; }
+
+    /**
+     * @return the value of the property.
+     */
+    public Object getValue() { return m_value; }
+
+    /**
+     * Fix the value of the property.
+     * @param value : the new value.
+     */
+    public void setValue(Object value) { m_value = value; }
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
new file mode 100644
index 0000000..a69f02a
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -0,0 +1,231 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.configuration;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+
+/**
+ * Handler managing the Configuration Admin.
+ * @author Clement Escoffier
+ */
+public class ConfigurationHandler implements Handler, ManagedService {
+
+	/**
+	 * Reference on the component manager.
+	 */
+	private ComponentManager m_manager;
+
+	/**
+	 * List of the configurable fields.
+	 */
+	private ConfigurableProperty[] m_configurableProperties = new ConfigurableProperty[0];
+
+	/**
+	 * PID of the component.
+	 */
+	private String m_pid;
+
+	/**
+	 * Service registration of the ManagedService provided by this handler.
+	 */
+	private ServiceRegistration m_sr;
+
+	/**
+	 * @return component manager of this handler.
+	 */
+	protected ComponentManager getComponentManager() { return m_manager; }
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+	 */
+	public void configure(ComponentManager cm, Element metadata) {
+		// Store the component manager
+		m_manager = cm;
+		m_configurableProperties = new ConfigurableProperty[0];
+
+		// Build the hashmap
+		Element[] configurables = metadata.getElements("ConfigurableProperty");
+
+		if (configurables.length > 0) { m_manager.register(this); }
+		else { return; }
+
+		for (int i = 0; i < configurables.length; i++) {
+			String fieldName = configurables[i].getAttribute("field");
+			String name = null;
+			if (configurables[i].containsAttribute("name")) { name = configurables[i].getAttribute("name"); }
+			else { name = fieldName; }
+			String value = null;
+			if (configurables[i].containsAttribute("value")) {
+				value = configurables[i].getAttribute("value");
+			}
+			ConfigurableProperty cp = new ConfigurableProperty(name, fieldName, value, this);
+			addProperty(cp);
+		}
+
+		// Get the PID :
+		if (metadata.containsAttribute("name")) { m_pid = metadata.getAttribute("name"); }
+		else { m_pid = metadata.getAttribute("className"); }
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stop()
+	 */
+	public void stop() {
+		// Unregister the service
+		if (m_sr != null) {
+			Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Unregister Managed Service");
+			m_sr.unregister();
+			m_sr = null;
+		}
+
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#start()
+	 */
+	public void start() {
+		// Unregister the service if already registred (it should not happen )
+		if (m_sr != null) { m_sr.unregister(); }
+
+		// Register the ManagedService
+		BundleContext bc = m_manager.getContext();
+		Dictionary properties = new Properties();
+		properties.put(Constants.SERVICE_PID, m_pid);
+
+		Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Register Managed Service");
+		m_sr = bc.registerService(ManagedService.class.getName(), this, properties);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+	 */
+	public void setterCallback(String fieldName, Object value) {
+		// Nothing to do
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+	 */
+	public Object getterCallback(String fieldName, Object value) {
+		// Check if the field is a configurable property
+		for (int i = 0; i < m_configurableProperties.length; i++) {
+			if (m_configurableProperties[i].getField().equals(fieldName)) {
+				return m_configurableProperties[i].getValue();
+			}
+		}
+		return value;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#isValid()
+	 */
+	public boolean isValid() {
+		return true;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+	 */
+	public void stateChanged(int state) {
+		if (state == ComponentManager.VALID) {
+			if (m_sr == null) { start(); }
+			return;
+		}
+		if (state == ComponentManager.INVALID) {
+			if (m_sr != null) { stop(); }
+			return;
+		}
+	}
+
+	/**
+	 * @see org.osgi.service.cm.ManagedService#updated(java.util.Dictionary)
+	 */
+	public void updated(Dictionary np) throws ConfigurationException {
+
+		if (np != null) {
+			Enumeration keysEnumeration = np.keys();
+			while (keysEnumeration.hasMoreElements()) {
+				String name = (String)keysEnumeration.nextElement();
+				Object value = np.get(name);
+				boolean find = false;
+				// Check if the field is a configurable property
+				for (int i = 0; !find && i < m_configurableProperties.length; i++) {
+					if (m_configurableProperties[i].getName().equals(name)) {
+						// Check if the value has change
+						if (m_configurableProperties[i].getValue() == null || !m_configurableProperties[i].getValue().equals(value)) {
+							m_configurableProperties[i].setValue(value); // Change the value
+							m_manager.setterCallback(m_configurableProperties[i].getField(), value); // says that the value has change
+						}
+						find = true;
+						// Else do nothing
+					}
+				}
+				if (!find) {
+					Activator.getLogger().log(Level.WARNING, "[" + m_manager.getComponentMetatada().getClassName() + "] The configuration is not valid, the property " + name + " is not a configurable property");
+					}
+				}
+			}
+		else { Activator.getLogger().log(Level.WARNING, "[" + m_manager.getComponentMetatada().getClassName() + "] The pushed configuration is null for " + m_pid); }
+
+	}
+
+	/**
+     * Add the given property metadata to the property metadata list.
+	 * @param p : property metdata to add
+	 */
+	protected void addProperty(ConfigurableProperty p) {
+        for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
+            if (m_configurableProperties[i] == p) { return; }
+        }
+
+        if (m_configurableProperties.length > 0) {
+        	ConfigurableProperty[] newProp = new ConfigurableProperty[m_configurableProperties.length + 1];
+            System.arraycopy(m_configurableProperties, 0, newProp, 0, m_configurableProperties.length);
+            newProp[m_configurableProperties.length] = p;
+            m_configurableProperties = newProp;
+        }
+        else {
+        	m_configurableProperties = new ConfigurableProperty[] {p};
+        }
+	}
+
+	/**
+	 * Check if the liste contains the property.
+	 * @param name : name of the property
+	 * @return true if the property exist in the list
+	 */
+	protected boolean containsProperty(String name) {
+		for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
+            if (m_configurableProperties[i].getName() == name) { return true; }
+        }
+		return false;
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
new file mode 100644
index 0000000..f617633
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
@@ -0,0 +1,498 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.ComponentManager;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Represent a service dependency either for a componenet dependency either for
+ * a provided service dependency. Date : 3 déc. 2005
+ * @author clément
+ */
+public class Dependency implements ServiceListener {
+
+    /**
+     * Dependency State : RESOLVED.
+     */
+    public static final int RESOLVED = 1;
+
+    /**
+     * Dependency State : UNRESOLVED.
+     */
+    public static final int UNRESOLVED = 2;
+
+    /**
+     * Link to the Component Manager.
+     * m_handler : ComponentManager
+     */
+    private DependencyHandler m_handler;
+
+
+    /**
+     * Metadata of the dependency.
+     * m_metadata : dependency metadata
+     */
+    private DependencyMetadata m_metadata;
+
+    /**
+     * Array of Service Objects.
+     * When cardinality = 1 : just the first element is returned
+     * When cardinality = ?..n : all the array is returned
+     * m_services : Array
+     */
+    private Object[] m_services = new Object[0];
+
+    /**
+     * Array of service references.
+     * m_ref : Array
+     */
+    private ServiceReference[] m_ref = new ServiceReference[0];
+
+    /**
+     * State of the dependency.
+     * 0 : stopped, 1 : valid, 2 : invalid.
+     * m_state : int
+     */
+    private int m_state;
+
+    /**
+     * True if the reference list change after the creation of a service object array.
+     */
+    private boolean m_change;
+
+    /**
+     * Class of the dependency.
+     * Usefull to create in the case of multiple dependency
+     */
+    private Class m_clazz;
+
+
+    /**
+     * Dependency contructor. After the creation the dependency is not started.
+     * @param dh : the dependency handler managing this dependency
+     * @param dm : the depednency metadata
+     */
+    public Dependency(DependencyHandler dh, DependencyMetadata dm) {
+    	m_handler = dh;
+        m_metadata = dm;
+    }
+
+    /**
+     * @return the dependency metadata.
+     */
+    public DependencyMetadata getMetadata() { return m_metadata; }
+
+    /**
+     * @return the dependency handler of this dependency.
+     */
+    public DependencyHandler getDependencyHandler() { return m_handler; }
+
+    /**
+     * @return the used service.
+     */
+    public HashMap getUsedServices() {
+    	HashMap hm = new HashMap();
+    	if (m_metadata.isMultiple()) {
+    		for (int i = 0; i < m_ref.length; i++) {
+    			if (i < m_services.length) { hm.put(((Object)m_services[i]).toString(), m_ref[i]); }
+    		}
+    	} else {
+    		if (m_ref.length != 0 && m_services.length != 0) { hm.put(((Object)m_services[0]).toString(), m_ref[0]); }
+    	}
+    	return hm;
+    }
+
+    /**
+     * A dependency is satisfied if it is optional of ref.length != 0.
+     * @return true is the dependency is satified
+     */
+    protected boolean isSatisfied() {
+        return m_metadata.isOptional() || m_ref.length != 0;
+    }
+
+    /**
+     * This method is called by the replaced code in the component implementation class.
+     * Construct the service object list is necessary.
+     * @return null or a service object or a list of service object according to the dependency.
+     */
+    protected Object get() {
+        Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Call get for a dependency on : " + m_metadata.getServiceSpecification()
+                        + " Multiple : " + m_metadata.isMultiple() + " Optional : " + m_metadata.isOptional());
+        try {
+
+            // 1 : Test if there is any change in the reference list :
+            if (!m_change) {
+                if (!m_metadata.isMultiple()) {
+                    if (m_services.length > 0) {
+                        return m_services[0]; }
+                    }
+                else {
+                    return m_services;
+               }
+            }
+
+            // 2 : Else there is a change in the list -> recompute the m_services array
+            Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Create a service array of " + m_clazz.getName());
+            m_services = (Object[])Array.newInstance(m_clazz, m_ref.length);
+
+            for (int i = 0; i < m_ref.length; i++) {
+                m_services[i] = m_handler.getComponentManager().getContext().getService(m_ref[i]);
+            }
+
+            m_change = false;
+            Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Create an array with the size " + m_services.length);
+
+
+            // 3 : The service object list is populated, I return either the first service object, either the array.
+            // Return null or an empty array if no service are found.
+            if (!m_metadata.isMultiple()) {
+                if (m_services.length > 0) {
+                    return m_services[0];
+                } else {
+                		// Load the nullable class
+                		String[] segment = m_metadata.getServiceSpecification().split("[.]");
+                		String className = "org.apache.felix.ipojo." + segment[segment.length - 1] + "Nullable";
+                		Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Try to load the nullable class for " + getMetadata().getServiceSpecification() + " -> " + className);
+                		Class nullableClazz = m_handler.getNullableClass(className);
+
+                		if (nullableClazz == null) {
+                			Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Cannot load the nullable class to return a dependency object for " + m_metadata.getField() + " -> " + m_metadata.getServiceSpecification());
+                			return null;
+                		}
+
+                		// The nullable class is loaded, create the object and return it
+                		Object instance = nullableClazz.newInstance();
+                		Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Nullable object created for " + getMetadata().getServiceSpecification() + " -> " + instance);
+                		return instance;
+                	}
+            }
+            else { // Multiple dependency
+                    return m_services;
+            }
+        } catch (Exception e) {
+            // There is a problem in the dependency resolving (like in stopping method)
+            if (!m_metadata.isMultiple()) {
+            	Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Return null, an exception was throwed in the get method -> " + e.getMessage());
+                return null; }
+            else {
+            	Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Return an empty array, an exception was throwed in the get method" + e.getMessage());
+                return Array.newInstance(m_clazz, 0); }
+        }
+    }
+
+    /**
+     * Method calld when a service event is throwed.
+     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+     * @param event : the received service event
+     */
+    public void serviceChanged(ServiceEvent event) {
+        synchronized (this) {
+
+            // If a service goes way.
+            if (event.getType() == ServiceEvent.UNREGISTERING) {
+                Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] A service is gone -> " + event.getServiceReference().getBundle());
+                if (containsSR(event.getServiceReference())) {
+                		// Call unbind method
+                		callUnbindMethod(event.getServiceReference());
+                		// Unget the service reference
+                    	m_handler.getComponentManager().getContext().ungetService(event.getServiceReference());
+                        int index = removeReference(event.getServiceReference());
+
+                        // Is the state valid or invalid
+                        if (m_ref.length == 0 && !m_metadata.isOptional()) {
+                            m_state = UNRESOLVED;
+                        }
+                        if (m_ref.length == 0 && m_metadata.isOptional()) {
+                            m_state = RESOLVED;
+                        }
+                        // Is there any change ?
+                        if (!m_metadata.isMultiple() && index == 0) { m_change = true; }
+                        if (!m_metadata.isMultiple() && index != 0) { m_change = false; }
+                        if (m_metadata.isMultiple()) { m_change = true;  }
+                    }
+                    m_handler.checkContext();
+                    return;
+            }
+
+            // If a service arrives
+            if (event.getType() == ServiceEvent.REGISTERED) {
+                // Add the new service inside the ref list
+                Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Add a service for a dependency");
+                addReference(event.getServiceReference());
+                if (isSatisfied()) {
+                    m_state = RESOLVED;
+                    if (m_metadata.isMultiple() || m_ref.length == 1) { m_change = true; }
+                    callBindMethod(event.getServiceReference());
+                }
+                m_handler.checkContext();
+            }
+
+        }
+    }
+
+    private void callUnbindMethod(ServiceReference ref) {
+        if (m_handler.getComponentManager().getState() == ComponentManager.VALID && m_metadata.isMultiple()) {
+        	for (int i = 0; i < m_metadata.getCallbacks().length; i++) {
+        		if (m_metadata.getCallbacks()[i].getMethodType() == DependencyCallback.UNBIND) {
+        			// Try to call the bind method with a service reference inside
+        			try {
+						m_metadata.getCallbacks()[i].call(new Object[] {ref});
+					} catch (NoSuchMethodException e) {
+						// The method was not found : try without service reference
+						try {
+							m_metadata.getCallbacks()[i].call();
+						} catch (NoSuchMethodException e1) {
+							// The method was not found : try with the service object
+							try {
+								m_metadata.getCallbacks()[i].call(new Object[] {m_handler.getComponentManager().getContext().getService(ref)});
+							} catch (NoSuchMethodException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Unbind method not found : " + e1.getMessage());
+								return;
+							} catch (IllegalAccessException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on unbind method : " + e2.getMessage());
+								return;
+							} catch (InvocationTargetException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the unbind method " + e2.getMessage());
+								return;
+							}
+						} catch (IllegalAccessException e1) {
+							Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on unbind method : " + e1.getMessage());
+							return;
+						} catch (InvocationTargetException e1) {
+							Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the unbind method " + e1.getMessage());
+							return;
+						}
+
+					} catch (IllegalAccessException e) {
+						Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e.getMessage());
+						return;
+					} catch (InvocationTargetException e) {
+						Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e.getMessage());
+						return;
+					}
+        		}
+        	}
+        }
+    }
+
+    private void callBindMethod(ServiceReference ref) {
+    	// call bind method :
+        if (m_handler.getComponentManager().getState() == ComponentManager.VALID && m_metadata.isMultiple()) {
+        	for (int i = 0; i < m_metadata.getCallbacks().length; i++) {
+        		if (m_metadata.getCallbacks()[i].getMethodType() == DependencyCallback.BIND) {
+        			// Try to call the bind method with a service reference inside
+        			try {
+						m_metadata.getCallbacks()[i].call(new Object[] {ref});
+					} catch (NoSuchMethodException e) {
+						// The method was not found : try without service reference
+						try {
+							m_metadata.getCallbacks()[i].call();
+						} catch (NoSuchMethodException e1) {
+							// The method was not found : try with the service object
+							try {
+								m_metadata.getCallbacks()[i].call(new Object[] {m_handler.getComponentManager().getContext().getService(ref)});
+							} catch (NoSuchMethodException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Bind method not found : " + e1.getMessage());
+								return;
+							} catch (IllegalAccessException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e2.getMessage());
+								return;
+							} catch (InvocationTargetException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e2.getMessage());
+								return;
+							}
+						} catch (IllegalAccessException e1) {
+							Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e1.getMessage());
+							return;
+						} catch (InvocationTargetException e1) {
+							Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e1.getMessage());
+							return;
+						}
+
+					} catch (IllegalAccessException e) {
+						Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e.getMessage());
+						return;
+					} catch (InvocationTargetException e) {
+						Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e.getMessage());
+						return;
+					}
+        		}
+        	}
+        }
+    }
+
+    /**
+     * Start the dependency.
+     */
+    public void start() {
+        // Construct the filter with the objectclass + filter
+        String classnamefilter = "(objectClass=" + m_metadata.getServiceSpecification() + ")";
+        String filter = "";
+        if (!m_metadata.getFilter().equals("")) {
+            filter = "(&" + classnamefilter + m_metadata.getFilter() + ")";
+        }
+        else {
+            filter = classnamefilter;
+        }
+
+        Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Start a dependency on : " + m_metadata.getServiceSpecification() + " with " + m_metadata.getFilter());
+        m_state = UNRESOLVED;
+
+        try {
+            m_clazz = m_handler.getComponentManager().getContext().getBundle().loadClass(m_metadata.getServiceSpecification());
+        } catch (ClassNotFoundException e) {
+            System.err.println("Cannot load the interface class for the dependency " + m_metadata.getField() + " [" + m_metadata.getServiceSpecification() + "]");
+            e.printStackTrace();
+        }
+
+        try {
+            // Look if the service is already present :
+            ServiceReference[] sr = m_handler.getComponentManager().getContext().getServiceReferences(
+            		m_metadata.getServiceSpecification(), filter);
+            if (sr != null) {
+                for (int i = 0; i < sr.length; i++) { addReference(sr[i]); }
+                m_state = RESOLVED;
+                }
+            // Register a listener :
+            m_handler.getComponentManager().getContext().addServiceListener(this, filter);
+            m_change = true;
+        }
+        catch (InvalidSyntaxException e1) {
+            Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] A filter is malformed : " + filter);
+            e1.printStackTrace();
+        }
+    }
+
+    /**
+     * Stop the dependency.
+     */
+    public void stop() {
+        Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Stop a dependency on : " + m_metadata.getServiceSpecification() + " with " + m_metadata.getFilter());
+        m_state = UNRESOLVED;
+
+        // Unget all services references
+        for (int i = 0; i < m_ref.length; i++) {
+        	m_handler.getComponentManager().getContext().ungetService(m_ref[i]);
+        }
+
+        m_ref = new ServiceReference[0];
+        m_handler.getComponentManager().getContext().removeServiceListener(this);
+        m_clazz = null;
+        m_services = null;
+    }
+
+    /**
+     * Return the state of the dependency.
+     * @return the state of the dependency (1 : valid, 2 : invalid)
+     */
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * Return the list of service reference.
+     * @return the service reference list.
+     */
+    public ServiceReference[] getServiceReferences() {
+        return m_ref;
+    }
+
+    /**
+     * Add a service reference in the current list.
+     * @param r : the new service reference to add
+     */
+    private void addReference(ServiceReference r) {
+        for (int i = 0; (m_ref != null) && (i < m_ref.length); i++) {
+            if (m_ref[i] == r) {
+                return;
+            }
+        }
+
+        if (m_ref != null) {
+            ServiceReference[] newSR = new ServiceReference[m_ref.length + 1];
+            System.arraycopy(m_ref, 0, newSR, 0, m_ref.length);
+            newSR[m_ref.length] = r;
+            m_ref = newSR;
+        }
+        else {
+            m_ref = new ServiceReference[] {r};
+        }
+    }
+
+    /**
+     * Find if a service registration il already registred.
+     * @param sr : the service registration to find.
+     * @return true if the service registration is already in the array
+     */
+    private boolean containsSR(ServiceReference sr) {
+        for (int i = 0; i < m_ref.length; i++) {
+            if (m_ref[i] == sr) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Remove a service reference in the current list.
+     * @param r : the new service reference to remove
+     * @return the index of the founded element, or -1 if the element is not found
+     */
+    private int removeReference(ServiceReference r) {
+        if (m_ref == null) {
+            m_ref = new ServiceReference[0];
+        }
+
+        int idx = -1;
+        for (int i = 0; i < m_ref.length; i++) {
+            if (m_ref[i] == r) {
+                idx = i;
+                break;
+            }
+        }
+
+        if (idx >= 0) {
+            // If this is the module, then point to empty list.
+            if ((m_ref.length - 1) == 0) {
+                m_ref = new ServiceReference[0];
+            }
+            // Otherwise, we need to do some array copying.
+            else {
+                ServiceReference[] newSR = new ServiceReference[m_ref.length - 1];
+                System.arraycopy(m_ref, 0, newSR, 0, idx);
+                if (idx < newSR.length)             {
+                    System.arraycopy(
+                            m_ref, idx + 1, newSR, idx, newSR.length - idx);
+                }
+                m_ref = newSR;
+            }
+        }
+        return idx;
+    }
+
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
new file mode 100644
index 0000000..f185678
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
@@ -0,0 +1,88 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.felix.ipojo.Callback;
+
+
+/**
+ * This class allwos the creation of callback when service dependency arrives or disappear.
+ * @author escoffie
+ *
+ */
+public class DependencyCallback {
+
+	/**
+	 * Bind method (called when a service arrives).
+	 */
+	public static final int BIND = 0;
+
+	/**
+	 * Unbind method (called when a service disappears).
+	 */
+	public static final int UNBIND = 1;
+
+	/**
+	 * Is the method a bind method or an unbind method ?
+	 */
+	private int m_methodType;
+
+    /**
+     * Callback object.
+     */
+    private Callback m_callback;
+
+
+    /**
+     * Constructor.
+     * @param dep : the dependency attached to this depednency callback
+     * @param method : the method to call
+     * @param methodType : is the method to call a bind method or an unbind method
+     * @param isStatic : is the method to call static ?
+     */
+    public DependencyCallback(Dependency dep, String method, int methodType, boolean isStatic) {
+    	m_methodType = methodType;
+        m_callback = new Callback(method, isStatic, dep.getDependencyHandler().getComponentManager());
+    }
+
+    /**
+     * @return the method type.
+     */
+    public int getMethodType() { return m_methodType; }
+
+    /**
+     * Call the callback method.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	m_callback.call();
+    }
+
+    /**
+     * Call the callback method.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	m_callback.call(arg);
+    }
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
new file mode 100644
index 0000000..7f4859c
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -0,0 +1,361 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.handlers.dependency.nullable.NullableObjectWriter;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * The dependency handler manages a list of dependencies.
+ * @author clément
+ */
+public class DependencyHandler implements Handler {
+
+	/**
+	 * The component manager using this handler.
+	 */
+	private ComponentManager m_componentManager;
+
+	/**
+	 * List of depednencies of the component.
+	 */
+	private Dependency[] m_dependencies = new Dependency[0];
+
+	/**
+	 * List of nullable class for optional dependencies.
+	 */
+	private Class[] m_nullableClasses = new Class[0];
+
+	/**
+	 * Classloader to use to load nullable classes.
+	 */
+	private NullableClassloader m_classloader;
+
+	/**
+	 * State of the handler.
+	 */
+	private int m_state;
+
+//	 ===================== Fields getters & setters =====================
+
+	private void addDependency(Dependency dep) {
+        for (int i = 0; (m_dependencies != null) && (i < m_dependencies.length); i++) {
+            if (m_dependencies[i] == dep) {
+                return;
+            }
+        }
+        if (m_dependencies.length > 0) {
+            Dependency[] newDep = new Dependency[m_dependencies.length + 1];
+            System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
+            newDep[m_dependencies.length] = dep;
+            m_dependencies = newDep;
+        }
+        else {
+        	m_dependencies = new Dependency[] {dep};
+        }
+	}
+
+	private void addNullableClass(Class clazz) {
+		for (int i = 0; (m_nullableClasses != null) && (i < m_nullableClasses.length); i++) {
+            if (m_nullableClasses[i] == clazz) {
+                return;
+            }
+        }
+        if (m_nullableClasses.length > 0) {
+            Class[] newClass = new Class[m_nullableClasses.length + 1];
+            System.arraycopy(m_nullableClasses, 0, newClass, 0, m_nullableClasses.length);
+            newClass[m_nullableClasses.length] = clazz;
+            m_nullableClasses = newClass;
+        }
+        else {
+        	m_nullableClasses = new Class[] {clazz};
+        }
+	}
+
+	/**
+	 * @return the dependency list
+	 */
+	public Dependency[] getDependencies() { return m_dependencies; }
+
+	/**
+	 * @return the component manager
+	 */
+	protected ComponentManager getComponentManager() { return m_componentManager; }
+
+//	 ===================== Handler implementation =====================
+
+	/**
+	 * Check the validity of the dependencies.
+	 */
+	protected void checkContext() {
+
+		synchronized (this) {
+
+			Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Check Context ...");
+
+			// Store the initial state
+			int initialState = m_state;
+
+			// Check the component dependencies
+			if (!validateComponentDependencies()) {
+				// The dependencies are not valid
+				if (initialState == ComponentManager.VALID) {
+					//There is a state change
+					m_state = ComponentManager.INVALID;
+					m_componentManager.check();
+				}
+				// Else do nothing, the component state stay UNRESOLVED
+			}
+			else {
+				// The dependencies are valid
+				if (initialState == ComponentManager.INVALID) {
+					//There is a state change
+					m_state = ComponentManager.VALID;
+					m_componentManager.check();
+				}
+				// Else do nothing, the component state stay VALID
+			}
+
+		}
+	}
+
+	private boolean checkDependency(Dependency dep) {
+        // Check the internal type of dependency
+            String field = dep.getMetadata().getField();
+
+            Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+        	String type = null;
+        	for (int i = 0; i < manipulation.getElements("Field").length; i++) {
+        		if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
+        			type = manipulation.getElements("Field")[i].getAttribute("type");
+        			break;
+        		}
+        	}
+
+            if (type == null) {
+            	Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] A declared dependency was not found in the class : " + dep.getMetadata().getField());
+            	return false;
+            }
+
+            if (type != null) {
+                if (type.endsWith("[]")) {
+                	// Set the dependency to multiple
+                	dep.getMetadata().setMultiple();
+                	type = type.substring(0, type.length() - 2);
+                	}
+
+                if (dep.getMetadata().getServiceSpecification() == null) { dep.getMetadata().setServiceSpecification(type); }
+
+                if (!dep.getMetadata().getServiceSpecification().equals(type)) {
+                    Activator.getLogger().log(Level.WARNING, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The field type [" + type + "] and the needed service interface [" + dep.getMetadata().getServiceSpecification() + "] are not the same");
+                    dep.getMetadata().setServiceSpecification(type);
+                }
+            }
+            else {
+                Activator.getLogger().log(Level.WARNING, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The declared dependency " + dep.getMetadata().getField() + "  does not exist in the code");
+            }
+		return true;
+	}
+
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+	 */
+	public void configure(ComponentManager cm, Element componentMetadata) {
+		// Fix the component manager
+		m_componentManager = cm;
+		m_dependencies = new Dependency[0];
+		m_nullableClasses = new Class[0];
+
+		// Create the dependency according to the component metadata
+		Element[] deps = componentMetadata.getElements("Dependency");
+		for (int i = 0; i < deps.length; i++) {
+			// Create the dependency metadata
+			String field = deps[i].getAttribute("field");
+			String serviceSpecification = null;
+			if (deps[i].containsAttribute("interface")) { serviceSpecification = deps[i].getAttribute("interface"); }
+			String filter = "";
+			if (deps[i].containsAttribute("filter")) { filter = deps[i].getAttribute("filter"); }
+			boolean optional = false;
+			if (deps[i].containsAttribute("optional") && deps[i].getAttribute("optional").equals("true")) { optional = true; }
+			DependencyMetadata dm = new DependencyMetadata(field, serviceSpecification, filter, optional);
+
+
+			Dependency dep = new Dependency(this, dm);
+			// Check the dependency :
+			if (checkDependency(dep)) { addDependency(dep); }
+			else { Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The dependency on " + dep.getMetadata().getField() + " is not valid"); }
+
+			// Look for dependency callback :
+			for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
+				String method = deps[i].getElements("Callback", "")[j].getAttribute("method");
+				String type = deps[i].getElements("Callback", "")[j].getAttribute("type");
+				int methodType = 0;
+				if (type.equals("bind")) { methodType = DependencyCallback.BIND; }
+				else { methodType = DependencyCallback.UNBIND; }
+				boolean isStatic = false;
+				if (deps[i].getElements("Callback", "")[j].containsAttribute("isStatic") && deps[i].getElements("Callback", "")[j].getAttribute("isStatic").equals("true")) { isStatic = true; }
+				DependencyCallback dc = new DependencyCallback(dep, method, methodType, isStatic);
+				dep.getMetadata().addDependencyCallback(dc);
+			}
+		}
+
+		if (deps.length > 0) {
+			m_componentManager.register(this);
+
+			// Create the nullable classloader
+			m_classloader = new NullableClassloader(m_componentManager.getContext().getBundle());
+
+		}
+	}
+
+	private void createNullableClass(Dependency dep) {
+		Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Try to load the nullable class for " + dep.getMetadata().getServiceSpecification());
+		// Try to load the nullable object :
+        String[] segment = dep.getMetadata().getServiceSpecification().split("[.]");
+        String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+
+        String resource = dep.getMetadata().getServiceSpecification().replace('.', '/') + ".class";
+        URL url =  m_componentManager.getContext().getBundle().getResource(resource);
+
+            try {
+                byte[] b = NullableObjectWriter.dump(url,  dep.getMetadata().getServiceSpecification());
+
+//                // DEBUG :
+//                try {
+//                    File file = new File("P:\\workspace\\iPOJO\\adapted\\" + className.replace('/', '.') + ".class");
+//                    file.createNewFile();
+//                    FileOutputStream fos = new FileOutputStream(file);
+//                    fos.write(b);
+//                    fos.close();
+//                } catch (Exception e3) {
+//                    System.err.println("Problem to write the adapted class on the file system  : " + e3.getMessage());
+//
+//                }
+
+                addNullableClass(m_classloader.defineClass(className.replace('/', '.'), b, null));
+                Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Nullable class created for " + dep.getMetadata().getServiceSpecification());
+
+            } catch (IOException e1) {
+                Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Cannot open a stream of an interface to generate the nullable class for " + dep.getMetadata().getServiceSpecification() + " -> " + e1.getMessage());
+            } catch (Exception e2) {
+            	Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Cannot load the nullable class for  " + dep.getMetadata().getServiceSpecification() + " -> " + e2.getMessage());
+            }
+	}
+
+	/**
+     * Return the nullable class corresponding to the given name.
+	 * @param name the needed type
+	 * @return the class correspondig to the name, or null if the class does not exist.
+	 */
+	protected Class getNullableClass(String name) {
+		for (int i = 0; i < m_nullableClasses.length; i++) {
+			Class c = m_nullableClasses[i];
+			if (c.getName().equals(name)) {
+				return c;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+	 */
+	public Object getterCallback(String fieldName, Object value) {
+		for (int i = 0; i < m_dependencies.length; i++) {
+			Dependency dep = m_dependencies[i];
+			if (dep.getMetadata().getField().equals(fieldName)) {
+				// The field name is a dependency, return the get
+				return dep.get();
+			}
+		}
+		// Else return the value
+		return value;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#isValid()
+	 */
+	public boolean isValid() {
+		return (m_state == ComponentManager.VALID);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+	 */
+	public void setterCallback(String fieldName, Object value) {
+	    // Do nothing
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#start()
+	 */
+	public void start() {
+		Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Start the dependency handler");
+
+		// Start the dependencies, for optional dependencies create Nullable class
+		for (int i = 0; i < m_dependencies.length; i++) {
+			Dependency dep = m_dependencies[i];
+			if (dep.getMetadata().isOptional() && !dep.getMetadata().isMultiple()) { createNullableClass(dep); }
+			dep.start();
+		}
+		// Check the state
+		m_state = m_componentManager.getState();
+		checkContext();
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+	 */
+	public void stateChanged(int state) {
+		// Another handler or the component manager itself change the state
+		if (m_state == ComponentManager.VALID && state == ComponentManager.INVALID) {
+			// The component is stopped => Stop the dependency tracking
+			stop();
+		}
+		m_state = state;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stop()
+	 */
+	public void stop() {
+		for (int i = 0; i < m_dependencies.length; i++) { m_dependencies[i].stop(); }
+	}
+
+	private boolean validateComponentDependencies() {
+		boolean valide = true;
+        for (int i = 0; i < m_dependencies.length; i++) {
+            Dependency dep = m_dependencies[i];
+            valide = valide & dep.isSatisfied();
+            if (!valide) {
+                Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Component Dependencies are not valid : " + dep.getMetadata().getServiceSpecification());
+                return false;
+            }
+        }
+        Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Component Dependencies are valid");
+        return valide;
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java
new file mode 100644
index 0000000..38c6595
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java
@@ -0,0 +1,148 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+/**
+ * Dependency Metadata.
+ * @author Clement Escoffier
+ */
+public class DependencyMetadata {
+
+	/**
+	 * Service Specification <=> Service contract (or interface in OSGi).
+	 */
+	private String m_serviceSpecification;
+
+	/**
+	 * LDAP filter.
+	 */
+	private String m_filter;
+
+	/**
+	 * is the dependency optional ?
+	 */
+	private boolean m_isOptional;
+
+	/**
+	 * is the dependency multiple ?
+	 */
+	private boolean m_isMultiple = false;
+
+	/**
+	 * List of dependency callbacks attached to this dependency.
+	 */
+	private DependencyCallback[] m_callbacks = new DependencyCallback[0];
+
+	/**
+	 * The field linking the metadata and the component implementation.
+	 */
+	private String m_field;
+
+	// Constructor
+
+	/**
+     * Constructor.
+	 * @param field : the field name
+	 * @param service : the interface name.
+	 * @param filter : the filter of the dependency
+	 * @param isOptional : is the dependency optional
+	 */
+	public DependencyMetadata(String field, String service, String filter, boolean isOptional) {
+		m_field = field;
+		m_serviceSpecification = service;
+		m_isOptional = isOptional;
+		m_filter = filter;
+	}
+
+	/**
+	 * Add a callback to the dependency.
+	 * @param cb : callback to add
+	 */
+	public void addDependencyCallback(DependencyCallback cb) {
+		 for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
+	            if (m_callbacks[i] == cb) { return; }
+	        }
+
+	        if (m_callbacks.length > 0) {
+	        	DependencyCallback[] newCallbacks = new DependencyCallback[m_callbacks.length + 1];
+	            System.arraycopy(m_callbacks, 0, newCallbacks, 0, m_callbacks.length);
+	            newCallbacks[m_callbacks.length] = cb;
+	            m_callbacks = newCallbacks;
+	        }
+	        else {
+	        	m_callbacks = new DependencyCallback[] {cb};
+	        }
+	}
+
+	// Getter
+
+	/**
+	 * @return Returns the m_field.
+	 */
+	public String getField() {
+		return m_field;
+	}
+
+	/**
+	 * @return Returns the m_filter.
+	 */
+	public String getFilter() {
+		return m_filter;
+	}
+
+	/**
+	 * @return Returns the m_isMultiple.
+	 */
+	public boolean isMultiple() {
+		return m_isMultiple;
+	}
+
+	/**
+	 * @return Returns the m_isOptional.
+	 */
+	public boolean isOptional() {
+		return m_isOptional;
+	}
+
+	/**
+	 * @return Returns the m_serviceSpecification.
+	 */
+	public String getServiceSpecification() {
+		return m_serviceSpecification;
+	}
+
+	/**
+	 * return true if the dependency is multiple.
+	 */
+	public void setMultiple() {
+		m_isMultiple = true;
+	}
+
+	/**
+     * Set the service specification.
+	 * @param serviceSpecification : the dependency service specification
+	 */
+	public void setServiceSpecification(String serviceSpecification) {
+		m_serviceSpecification = serviceSpecification;
+	}
+
+	/**
+	 * @return the list of the callbacks
+	 */
+	public DependencyCallback[] getCallbacks() { return m_callbacks; }
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java
new file mode 100644
index 0000000..b490fdf
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java
@@ -0,0 +1,103 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * iPOJO Classloader.
+ * This classloadert is used to load manipulated class.
+ * @author Clement Escoffier
+ */
+public class NullableClassloader extends ClassLoader {
+
+	 /**
+     * The owner bundle.
+     * m_bundle : Bundle
+     */
+    private Bundle  m_bundle;
+
+    /**
+     * Constructor.
+     * @param b : the owner bundle
+     */
+    public NullableClassloader(Bundle b) {
+        m_bundle = b;
+    }
+
+    /**
+     * load the class.
+     * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+     * @param name : the name of the class
+     * @param resolve : should be the class resolve now ?
+     * @return : the loaded class
+     * @throws ClassNotFoundException : the class to load is not found
+     */
+    protected synchronized Class loadClass(final String name,
+            final boolean resolve) throws ClassNotFoundException {
+
+        Class clazz = null;
+        //Activator.getLogger().log(Level.WARNING, "Bundle " + m_bundle.getBundleId() + " -> Try to load : " + name);
+
+        if (m_bundle != null) { clazz = m_bundle.loadClass(name); }
+
+        return clazz;
+    }
+
+
+    /**
+     * Return the URL of the asked ressource.
+     * @param arg : the name of the resource to find.
+     * @return the URL of the resource.
+     * @see java.lang.ClassLoader#getResource(java.lang.String)
+     */
+    public URL getResource(String arg) {
+        return m_bundle.getResource(arg);
+    }
+
+    /**
+     * .
+     * @param arg : resource to find
+     * @return : the enumeration found
+     * @throws IOException : if the lookup failed.
+     * @see java.lang.ClassLoader#getResources(java.lang.String)
+     */
+    public Enumeration getRessources(String arg) throws IOException {
+        return m_bundle.getResources(arg);
+    }
+
+    /**
+     * The defineClass method for GenClassLoader.
+     * @param name : name of the class
+     * @param b : the byte array of the class
+     * @param domain : the protection domain
+     * @return : the defined class.
+     * @throws Exception : if a problem is detected during the loading
+     */
+    public Class defineClass(String name, byte[] b,
+            ProtectionDomain domain) throws Exception {
+    	Class clazz =  super.defineClass(name, b, 0, b.length, domain);
+    	return clazz;
+    }
+
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java
new file mode 100644
index 0000000..ff49abd
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java
@@ -0,0 +1,89 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency.nullable;
+
+/**
+ * Reprensent of method description.
+ * The goal of this class, is to be able to generate a proxy class, or a nullable class from an interface.
+ * @author Clement Escoffier
+ *
+ */
+public class MethodSignature {
+
+    /**
+     * Nmae of the method.
+     */
+    private String m_name;
+
+    /**
+     * Descriptor of the method.
+     */
+    private String m_desc;
+
+    /**
+     * Signature of the method.
+     */
+    private String m_signature;
+
+    /**
+     * Exception thored by the method.
+     */
+    private String[] m_exception;
+
+    /**
+     * MethodSignature constructor.
+     * Describe a method.
+     * @param name : name of the method
+     * @param desc : descriptor of the method
+     * @param sign : signature of the method
+     * @param exc : exception throwed by the method
+     */
+    public MethodSignature(String name, String desc, String sign, String[] exc) {
+        m_name = name;
+        m_desc = desc;
+        m_signature = sign;
+        m_exception = exc;
+    }
+
+    /**
+     * @return the description of the method.
+     */
+    public String getDesc() {
+        return m_desc;
+    }
+
+    /**
+     * @return the String array of exception throwed by the method.
+     */
+    public String[] getException() {
+        return m_exception;
+    }
+
+    /**
+     * @return the name of the method.
+     */
+    public String getName() {
+        return m_name;
+    }
+
+    /**
+     * @return the signature of the method.
+     */
+    public String getSignature() {
+        return m_signature;
+    }
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java
new file mode 100644
index 0000000..d1b341e
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java
@@ -0,0 +1,129 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency.nullable;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/** This class implement a class visitor. It store all method signature of
+ * the visited interface. Then it returns these class signatures for the proxy
+ * generation or the nullable class.
+ * Date : 4/9/2005
+ * @author Clement Escoffier
+ */
+public class MethodSignatureVisitor implements ClassVisitor, Opcodes {
+
+    /**
+     * Array of method signature.
+     */
+    private MethodSignature[] m_methods;
+
+
+    /**
+     * Constructor.
+     */
+    public MethodSignatureVisitor() { }
+
+    /**
+     * Visit a method, store the information about the method.
+     * @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+     * @param access : Access modifier
+     * @param name : name of the visited method
+     * @param signature : singature of the visited element (null if not generic)
+     * @param desc : descriptor of the method
+     * @param exceptions : execption clause
+     * @return always null (not code visitor needed)
+     */
+    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+        //Store method signature for each visited method
+        m_methods = addMethod(m_methods, new MethodSignature(name, desc, signature, exceptions));
+        return null;
+    }
+
+    /**
+     * @return the mthod signature array.
+     */
+    public MethodSignature[] getMethods() {
+        return m_methods;
+    }
+
+    /**
+     * Return the new array of Method Signature by adding the given list and the given element.
+     * @param list : the current array
+     * @param method : the element to add
+     * @return the new array
+     */
+    public static MethodSignature[] addMethod(MethodSignature[] list, MethodSignature method) {
+        if (list != null) {
+            MethodSignature[] newList = new MethodSignature[list.length + 1];
+            System.arraycopy(list, 0, newList, 0, list.length);
+            newList[list.length] = method;
+            return newList;
+        }
+        else {
+            list = new MethodSignature[] {method};
+            return list;
+        }
+
+    }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visit(int, int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+     */
+    public void visit(int arg0, int arg1, String arg2, String arg3, String arg4, String[] arg5) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitSource(java.lang.String, java.lang.String)
+     */
+    public void visitSource(String arg0, String arg1) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitOuterClass(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void visitOuterClass(String arg0, String arg1, String arg2) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitAnnotation(java.lang.String, boolean)
+     */
+    public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) { return null; }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitAttribute(org.objectweb.asm.Attribute)
+     */
+    public void visitAttribute(Attribute arg0) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitInnerClass(java.lang.String, java.lang.String, java.lang.String, int)
+     */
+    public void visitInnerClass(String arg0, String arg1, String arg2, int arg3) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
+     */
+    public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4) { return null; }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitEnd()
+     */
+    public void visitEnd() { }
+
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
new file mode 100644
index 0000000..1eb0edf
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
@@ -0,0 +1,124 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency.nullable;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/** Create the proxy class.
+ * @author clément
+ */
+public class NullableObjectWriter implements Opcodes {
+
+    /** Return the proxy classname for the contract contractname
+     * on the service object soc.
+     * @param url URL of the needed contract
+     * @param contractName String
+     * @return byte[]
+     */
+    public static byte[] dump(URL url,
+            String contractName) {
+
+        ClassReader cr = null;
+        InputStream is = null;
+        byte[] b = null;
+        try {
+            is = url.openStream();
+            cr = new ClassReader(is);
+            MethodSignatureVisitor msv = new MethodSignatureVisitor();
+            cr.accept(msv, true);
+            is.close();
+
+            ClassWriter cw = new ClassWriter(true);
+
+            String[] segment = contractName.split("[.]");
+            String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+
+
+            // Create the class
+            cw.visit(V1_2, ACC_PUBLIC + ACC_SUPER, className, null,
+                    "java/lang/Object", new String[]{contractName.replace('.', '/'), "org/apache/felix/ipojo/Nullable"});
+
+            // Inject a constructor <INIT>()V
+                MethodVisitor cst = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+                cst.visitVarInsn(ALOAD, 0);
+                cst.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+                cst.visitInsn(RETURN);
+                cst.visitMaxs(0, 0);
+                cst.visitEnd();
+
+            // Methods Generation :
+            MethodSignature[] methods = msv.getMethods();
+
+            for (int i = 0; i < methods.length; ++i) {
+                MethodSignature method = methods[i];
+                String desc = method.getDesc();
+                String name = method.getName();
+                String sign = method.getSignature();
+                String[] exc = method.getException();
+
+                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, name, desc, sign, exc);
+
+                Type returnType = Type.getReturnType(desc);
+                    // TODO : manage the other type primitive
+                    // Primitive type :
+                    switch (returnType.getSort()) {
+                    case Type.BOOLEAN:
+                    case Type.INT:
+                        // Integer or Boolean : return 0 ( false)
+                        mv.visitInsn(ICONST_0);
+                        mv.visitInsn(IRETURN);
+                        break;
+                    case Type.DOUBLE:
+                        // Double : return 0.0
+                        mv.visitInsn(DCONST_0);
+                        mv.visitInsn(DRETURN);
+                        break;
+                    case Type.ARRAY :
+                    case Type.OBJECT :
+                        // Return always null for array and object
+                        mv.visitInsn(ACONST_NULL);
+                        mv.visitInsn(ARETURN);
+                        break;
+                    case Type.VOID :
+                        mv.visitInsn(RETURN);
+                        break;
+                    default :
+                        System.err.println("Type not yet managed : " + returnType);
+                    }
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+
+            // End process
+            cw.visitEnd();
+            b =  cw.toByteArray();
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return b;
+    }
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
new file mode 100644
index 0000000..1bc4899
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
@@ -0,0 +1,67 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.lifecycle.callback;
+
+import java.lang.reflect.InvocationTargetException;
+import org.apache.felix.ipojo.Callback;
+
+/**
+ * This class is the implementation of callback on lifecycle transition.
+ * @author Clement Escoffier
+ *
+ */
+public class LifecycleCallback {
+
+
+    /**
+     * Metadata of the callback.
+     */
+    private LifecycleCallbackMetadata m_metadata;
+
+    /**
+     * Callback object.
+     */
+    private Callback m_callback;
+
+    /**
+     * LifecycleCallback constructor.
+     * @param hh : the callback handler calling the callback
+     * @param hm : the callback metadata
+     */
+    public LifecycleCallback(LifecycleCallbackHandler hh, LifecycleCallbackMetadata hm) {
+        m_metadata = hm;
+        m_callback = new Callback(hm.getMethod(), hm.isStatic(), hh.getComponentManager());
+    }
+
+    /**
+     * @return : the metadata of the hook
+     */
+    public LifecycleCallbackMetadata getMetadata() {
+        return m_metadata;
+    }
+
+    /**
+     * Call the hook method when the transition from inital to final state is detected.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	m_callback.call();
+    }
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
new file mode 100644
index 0000000..f20d3f6
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
@@ -0,0 +1,160 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.lifecycle.callback;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Lifecycle callback handler.
+ * @author Clement Escoffier
+ */
+public class LifecycleCallbackHandler implements Handler {
+
+	/**
+	 * The list of the callback of the component.
+	 */
+	private LifecycleCallback[] m_callbacks = new LifecycleCallback[0];
+
+	/**
+	 * State of the component manager (unresolved at the beginning).
+	 */
+	private int m_state = ComponentManager.INVALID;
+
+	/**
+	 * The component manager.
+	 */
+	private ComponentManager m_componentManager;
+
+	 /**
+     * Add the given Hook to the hook list.
+     * @param hk : the element to add
+     */
+    private void addCallback(LifecycleCallback hk) {
+        for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
+            if (m_callbacks[i] == hk) { return; }
+        }
+
+        if (m_callbacks.length > 0) {
+            LifecycleCallback[] newHk = new LifecycleCallback[m_callbacks.length + 1];
+            System.arraycopy(m_callbacks, 0, newHk, 0, m_callbacks.length);
+            newHk[m_callbacks.length] = hk;
+            m_callbacks = newHk;
+        }
+        else {
+        	m_callbacks = new LifecycleCallback[] {hk};
+        }
+
+    }
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+	 */
+	public void configure(ComponentManager cm, Element metadata) {
+		m_componentManager = cm;
+		m_callbacks = new LifecycleCallback[0];
+
+		Element[] hooksMetadata = metadata.getElements("callback");
+		for (int i = 0; i < hooksMetadata.length; i++) {
+			// Create an HookMetadata object
+			String initialState = hooksMetadata[i].getAttribute("initial");
+			String finalState = hooksMetadata[i].getAttribute("final");
+			String method = hooksMetadata[i].getAttribute("method");
+			boolean isStatic = false;
+			if (hooksMetadata[i].containsAttribute("isStatic") && hooksMetadata[i].getAttribute("isStatic").equals("true")) { isStatic = true; }
+
+			LifecycleCallbackMetadata hm = new LifecycleCallbackMetadata(initialState, finalState, method, isStatic);
+
+			LifecycleCallback hk = new LifecycleCallback(this, hm);
+			addCallback(hk);
+		}
+		if (m_callbacks.length > 0) { m_componentManager.register(this); }
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stop()
+	 */
+	public void stop() {
+		m_state = ComponentManager.INVALID;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#start()
+	 */
+	public void start() {
+		Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Start the life cycle callback handler");
+	}
+
+	/**
+	 * Do nothing.
+	 * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+	 */
+	public void setterCallback(String fieldName, Object value) {
+		// Do nothing
+	}
+
+	/**
+	 * Do nothing, return the initial value.
+	 * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+	 */
+	public Object getterCallback(String fieldName, Object value) {
+		return value;
+	}
+
+	/**
+	 * Return true.
+	 * @see org.apache.felix.ipojo.Handler#isValid()
+	 */
+	public boolean isValid() {
+		return true;
+	}
+
+	/**
+	 * @return the component manager
+	 */
+	protected ComponentManager getComponentManager() { return m_componentManager; }
+
+	/**
+	 * When the state change call the associated hooks.
+	 * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+	 */
+	public void stateChanged(int state) {
+		Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] State changed in callback handler, check " + m_callbacks.length + " callbacks. Transition : " + m_state + " -> " + state);
+		for (int i = 0; i < m_callbacks.length; i++) {
+			if (m_callbacks[i].getMetadata().getInitialState() == m_state && m_callbacks[i].getMetadata().getFinalState() == state) {
+				try {
+					Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Call the callback : " + m_callbacks[i].getMetadata().getMethod());
+					m_callbacks[i].call();
+				} catch (NoSuchMethodException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " is not found : " + e.getMessage());
+				} catch (IllegalAccessException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " is not accessible : " + e.getMessage());
+				} catch (InvocationTargetException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " has throws an exception : " + e.getMessage() + " -> " + e.getCause());
+				}
+			}
+		}
+		// Update to internal state
+		m_state = state;
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java
new file mode 100644
index 0000000..cc032a0
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java
@@ -0,0 +1,96 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.lifecycle.callback;
+
+import org.apache.felix.ipojo.ComponentManager;
+
+/**
+ * Lifecycle callback metadata.
+ * @author Clement Escoffier
+ */
+public class LifecycleCallbackMetadata {
+
+	/**
+	 * Initial state of the transition.
+	 */
+	private int m_initialState;
+
+	/**
+	 * Final state of the transition.
+	 */
+	private int m_finalState;
+
+	/**
+	 * Method to call.
+	 */
+	private String m_method;
+
+	/**
+	 * is the method a static method ?
+	 */
+	private boolean m_isStatic;
+
+	// Constructor
+
+	/**
+     * Constructor.
+	 * @param initialState : initial state
+	 * @param finalState : final state
+	 * @param method : method name
+	 * @param isStatic : is the method a static method ?
+	 */
+	public LifecycleCallbackMetadata(String initialState, String finalState, String method, boolean isStatic) {
+		if (initialState.equals("VALID")) { m_initialState = ComponentManager.VALID; }
+		if (initialState.equals("INVALID")) { m_initialState = ComponentManager.INVALID; }
+		if (finalState.equals("VALID")) { m_finalState = ComponentManager.VALID; }
+		if (finalState.equals("INVALID")) { m_finalState = ComponentManager.INVALID; }
+
+		m_method = method;
+		m_isStatic = isStatic;
+	}
+
+	// Getters
+
+	/**
+	 * @return Returns the m_finalState.
+	 */
+	public int getFinalState() {
+		return m_finalState;
+	}
+
+	/**
+	 * @return Returns the m_initialState.
+	 */
+	public int getInitialState() {
+		return m_initialState;
+	}
+
+	/**
+	 * @return Returns the m_isStatic.
+	 */
+	public boolean isStatic() {
+		return m_isStatic;
+	}
+
+	/**
+	 * @return Returns the m_method.
+	 */
+	public String getMethod() {
+		return m_method;
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java
new file mode 100644
index 0000000..c1dfe05
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java
@@ -0,0 +1,177 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Represent a property i.e. a set : [name, type, value].
+ * A property can be attached to a field.
+ * The value of the property is thefield value.
+ * When the value change, the published value change too.
+ * Date : 5 févr. 2006
+ * @author clément
+ */
+public class Property {
+
+    /**
+     * A property is link with a service.
+     * This field represent this provided service.
+     * m_providedService : ProvidedService
+     */
+    private ProvidedService m_providedService;
+
+    /**
+     * Value of the property (before we know the type).
+     */
+    private Object m_value;
+
+    /**
+     * Metadata of the property.
+     */
+    private PropertyMetadata m_metadata;
+
+    /**
+     * Property constructor.
+     * @param ps : the provided service
+     * @param pm : metadata of the property
+     */
+    public Property(ProvidedService ps, PropertyMetadata pm) {
+    	m_providedService = ps;
+    	m_metadata = pm;
+
+    	// Fix the type of the property if null
+    	if (pm.getType() == null) {
+    		// If the type is not found, it is a dynamic property
+    		Element manipulation = m_providedService.getComponentManager().getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+        	String type = null;
+        	String field = m_metadata.getField();
+        	for (int i = 0; i < manipulation.getElements("Field").length; i++) {
+        		if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
+        			type = manipulation.getElements("Field")[i].getAttribute("type");
+        			break;
+        		}
+        	}
+
+    		pm.setType(type);
+    	}
+
+    	if (pm.getValue() != null) { setValue(pm.getValue()); }
+    }
+
+    /**
+     * @return the Object value of the property
+     */
+    protected Object get() {
+        if (m_value == null) {
+            Activator.getLogger().log(Level.INFO, "[" + m_providedService.getComponentManager().getComponentMetatada().getClassName() + "] A property " + m_metadata.getName() + " can not be returned : no value assigned");
+        }
+        return m_value;
+    }
+
+
+    /**
+     * @return the property metadata.
+     */
+    public PropertyMetadata getMetadata() {
+    	return m_metadata;
+    }
+
+    /**
+     * This method is automaticaly called when the value of the property is changed.
+     * Set the value of a property.
+     * @param s : the new value of the property (in String)
+     */
+    protected void set(String s) {
+        setValue(s);
+        m_providedService.update();
+    }
+
+    /**
+     * This method is called when the value of the property is changed.
+     * Set the value of a property.
+     * @param o : the new value of the property (object)
+     */
+    protected void set(Object o) {
+        m_value = o;
+        m_providedService.update();
+    }
+
+    /**
+     * Set the provided service of this property.
+     * @param ps : the provided service to attached.
+     */
+    void setProvidedService(ProvidedService ps) {
+        m_providedService = ps;
+    }
+
+    /**
+     * Set the value of the property.
+     * @param value : value of the property (String)
+     */
+    private void setValue(String value) {
+    	String type = m_metadata.getType();
+
+    	Activator.getLogger().log(Level.INFO, "[" + m_providedService.getComponentManager().getComponentMetatada().getClassName() + "] Set the value of the property " + m_metadata.getName() + " [" + m_metadata.getType() + "] " + " with the value : " + value);
+
+        if (type.equals("string") || type.equals("String")) { m_value = new String(value); return; }
+        if (type.equals("boolean")) { m_value = new Boolean(value); return; }
+        if (type.equals("byte")) { m_value = new Byte(value); return; }
+        if (type.equals("short")) { m_value = new Short(value); return; }
+        if (type.equals("int")) { m_value = new Integer(value); return; }
+        if (type.equals("long")) { m_value = new Long(value); return; }
+        if (type.equals("float")) { m_value = new Float(value); return; }
+        if (type.equals("double")) { m_value = new Double(value); return; }
+
+        // Else it is a neither a primitive type neither a String -> create the object by calling a constructor with a string in argument.
+        try {
+            Class c = m_providedService.getComponentManager().getContext().getBundle().loadClass(type);
+            //Class string = m_providedService.getComponentManager().getContext().getBundle().loadClass("java.lang.String");
+            Constructor cst = c.getConstructor(new Class[] {String.class});
+            m_value = cst.newInstance(new Object[] {value});
+        } catch (ClassNotFoundException e) {
+            System.err.println("Class not found exception in setValue on " + type);
+            e.printStackTrace();
+        } catch (SecurityException e) {
+            e.printStackTrace();
+        } catch (NoSuchMethodException e) {
+            System.err.println("Constructor not found exeption in setValue on " + type);
+            e.printStackTrace();
+        } catch (IllegalArgumentException e) {
+            System.err.println("Argument problem to call the constructor of the type " + type);
+            e.printStackTrace();
+        } catch (InstantiationException e) {
+            System.err.println("Instantiation problem  " + type);
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            System.err.println("Invocation problem " + type);
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @return the value of the property.
+     */
+    public Object getValue() { return m_value; }
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java
new file mode 100644
index 0000000..9b90e76
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java
@@ -0,0 +1,93 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+/**
+ * Property metadata : either static either dynamic.
+ * @author Clement Escoffier
+ */
+public class PropertyMetadata {
+
+	/**
+	 * Field of the property.
+	 */
+	private String m_field;
+
+	/**
+	 * Name of the property.
+	 */
+	private String m_name;
+
+	/**
+	 * Type of the property.
+	 */
+	private String m_type;
+
+	/**
+	 * String value of the property (initial value).
+	 */
+	private String m_value;
+
+	//Constructor
+
+	/**
+     * Constructor.
+	 * @param name : name of the property
+	 * @param field : field of the property
+	 * @param type : type of the property
+	 * @param value : initial value of the property
+	 */
+	public PropertyMetadata(String name, String field, String type, String value) {
+		m_name = name;
+		m_field = field;
+		m_type = type;
+		m_value = value;
+
+		// Dynamic property case :
+		if (m_field != null) {
+			if (m_name == null) { m_name = m_field; }
+		}
+	}
+
+	/**
+	 * @return the field name.
+	 */
+	public String getField() { return m_field; };
+
+	/**
+	 * @return the property name.
+	 */
+	public String getName() { return m_name; };
+
+	/**
+	 * @return the type of the property.
+	 */
+	public String getType() { return m_type; };
+
+	/**
+	 * @return the initial value.
+	 */
+	public String getValue() { return m_value; }
+
+	/**
+     * Set the type of the property (dynamic property only).
+	 * @param type : the type of the property.
+	 */
+	public void setType(String type) { m_type = type; }
+
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedService.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedService.java
new file mode 100644
index 0000000..041642d
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedService.java
@@ -0,0 +1,281 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+import java.util.Properties;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Activator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+
+/**
+ * Provided Service represent a provided service by the component.
+ * Date : 3 déc. 2005
+ * @author clément
+ *
+ */
+public class ProvidedService implements ServiceFactory {
+
+    /**
+     * Service State : REGISTRED.
+     */
+    public static final int REGISTERED = 1;
+
+    /**
+     * Service State : UNREGISTRED.
+     */
+    public static final int UNREGISTERED = 0;
+
+    /**
+     * Factory Policy : SINGLETON_FACTORY.
+     */
+    public static final int SINGLETON_FACTORY = 0;
+
+    /**
+     * Factory policy : SERVICE_FACTORY.
+     */
+    public static final int SERVICE_FACTORY = 1;
+
+    /**
+     * Factory policy : COMPONENT_FACTORY.
+     * TODO : Component_factory behavior
+     */
+    public static final int COMPONENT_FACTORY = 2;
+
+    /**
+     * The service registration.
+     * is null when the service is not registred.
+     * m_serviceRegistration : ServiceRegistration
+     */
+    private ServiceRegistration m_serviceRegistration;
+
+    /**
+     * Link to the component manager.
+     * m_handler : ComponentManager
+     */
+    private ProvidedServiceHandler m_handler;
+
+    /**
+     * Provided service metadata.
+     */
+    private ProvidedServiceMetadata m_metadata;
+
+    /**
+     * State of the provided service.
+     */
+    private int m_state;
+
+    /**
+     * Properties Array.
+     */
+    private Property[] m_properties = new Property[0];
+
+
+    /**
+     * Construct a provided service object.
+     * @param handler : the provided service handler.
+     * @param psm : the provided service metadata.
+     */
+    public ProvidedService(ProvidedServiceHandler handler, ProvidedServiceMetadata psm) {
+        m_handler = handler;
+        m_metadata = psm;
+        for (int i = 0; i < psm.getProperties().length; i++) {
+        	Property prop = new Property(this, ((PropertyMetadata)psm.getProperties()[i]));
+        	addProperty(prop);
+        }
+    }
+
+    /**
+     * Add the given property to the property list.
+     * @param p : the element to add
+     */
+    private void addProperty(Property p) {
+        for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
+            if (m_properties[i] == p) { return; }
+        }
+
+        if (m_properties.length > 0) {
+            Property[] newProp = new Property[m_properties.length + 1];
+            System.arraycopy(m_properties, 0, newProp, 0, m_properties.length);
+            newProp[m_properties.length] = p;
+            m_properties = newProp;
+        }
+        else { m_properties = new Property[] {p}; }
+    }
+
+    /**
+     * @return the service reference of the provided service (null if the service is not published).
+     */
+    public ServiceReference getServiceReference() {
+    	if (m_serviceRegistration != null) { return m_serviceRegistration.getReference(); }
+    	else { return null; }
+    }
+
+    /**
+     * Return a service object for the dependency.
+     * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+     * @param bundle : the bundle
+     * @param registration : the service registration of the registred service
+     * @return : a new service object or a already created service object (in the case of singleton)
+     */
+    public Object getService(Bundle bundle, ServiceRegistration registration) {
+
+    	switch(m_metadata.getFactoryPolicy()) {
+
+    	case SINGLETON_FACTORY :
+            return m_handler.getComponentManager().getInstance();
+
+    	case SERVICE_FACTORY :
+    		return m_handler.getComponentManager().createInstance();
+
+    	case COMPONENT_FACTORY :
+    		//TODO Component Factory Behavior
+    		return null;
+
+    	default :
+    		Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Unknown factory policy for " + m_metadata.getServiceSpecification() + " : " + m_metadata.getFactoryPolicy());
+    		return null;
+    	}
+
+    }
+
+    /**
+     * The unget method.
+     * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+     * @param bundle : bundle
+     * @param registration : service registration
+     * @param service : service object
+     */
+    public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+        //Nothing to do
+    }
+
+//    /**
+//     * Validate the service dependencies of the current provided service.
+//     * @return true if the service dependencies are valid
+//     */
+//    public boolean validate() {
+//        boolean valide = true;
+//        for (int i = 0; i < m_dependencies.length; i++) {
+//            Dependency dep = m_dependencies[i];
+//            valide = valide & dep.isSatisfied();
+//            if (!valide) {
+//                ComponentManager.getLogger().log(Level.INFO, "Service Dependency  for " + m_interface + " not valid : " + dep.getInterface());
+//                return false;
+//            }
+//        }
+//        ComponentManager.getLogger().log(Level.INFO, "Service dependencies for " + m_interface + " are valid");
+//        return valide;
+//    }
+
+    /**
+     * Register the service.
+     * The service object must be able to serve this service.
+     * To avoid cycle in Check Context, the registred service is set to registred before the real registration.
+     */
+    protected void registerService() {
+    	if (m_state != REGISTERED) {
+            String spec = "";
+            for (int i = 0; i < m_metadata.getServiceSpecification().length; i++) {
+                spec = spec + m_metadata.getServiceSpecification()[i] + ", ";
+            }
+    			Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Register the service : " + spec);
+    			// Contruct the service properties list
+    			Properties serviceProperties = getServiceProperties();
+
+    			m_state = REGISTERED;
+    			m_serviceRegistration = m_handler.getComponentManager().getContext().registerService(m_metadata.getServiceSpecification(), this, serviceProperties);
+    	}
+    }
+
+    /**
+     * Unregister the service.
+     */
+    protected void unregisterService() {
+    	if (m_state == REGISTERED) {
+    		try {
+    			m_serviceRegistration.unregister();
+    			m_serviceRegistration = null;
+    		} catch (Exception e) { return; }
+			m_state = UNREGISTERED;
+    	}
+    }
+
+    /**
+     * @return The state of the provided service.
+     */
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * @return the component manager.
+     */
+    protected ComponentManager getComponentManager() {
+    	return m_handler.getComponentManager();
+    }
+
+    /**
+     * Return the list of properties attached to this service.
+     * This list contains only property where a value are assigned.
+     * @return the properties attached to the provided service.
+     */
+    private Properties getServiceProperties() {
+        // Contruct the service properties list
+        Properties serviceProperties = new Properties();
+        for (int i = 0; i < m_properties.length; i++) {
+            if (m_properties[i].get() != null) {
+                serviceProperties.put(m_properties[i].getMetadata().getName(), m_properties[i].get().toString());
+            }
+        }
+        return serviceProperties;
+    }
+
+    /**
+     * @return the properties attached to the provided service.
+     */
+    public Property[] getProperties() {
+        return m_properties;
+    }
+
+    /**
+     * Update refresh the service properties.
+     * The new list of properties is sended to the service registry.
+     */
+    protected void update() {
+        // Update the service properties
+
+        // Contruct the service properties list
+        Properties serviceProperties = getServiceProperties();
+
+        // Update the service registration
+        if (m_state == REGISTERED) { m_serviceRegistration.setProperties(serviceProperties); }
+    }
+
+	/**
+	 * @return the propvided service metadata.
+	 */
+	public ProvidedServiceMetadata getMetadata() {
+		return m_metadata;
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceHandler.java
new file mode 100644
index 0000000..d9b98cc
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceHandler.java
@@ -0,0 +1,306 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * @author Clement Escoffier
+ *
+ */
+public class ProvidedServiceHandler implements Handler {
+
+
+	/**
+	 * The list of the provided service.
+	 */
+	private ProvidedService[] m_providedServices = new ProvidedService[0];
+
+	/**
+	 * The component manager.
+	 */
+	private ComponentManager m_componentManager;
+
+	private void addProvidedService(ProvidedService ps) {
+	        //  Verify that the provided service is not already in the array.
+	        for (int i = 0; (m_providedServices != null) && (i < m_providedServices.length); i++) {
+	            if (m_providedServices[i] == ps) { return; }
+	        }
+
+	        if (m_providedServices.length > 0) {
+	            ProvidedService[] newPS = new ProvidedService[m_providedServices.length + 1];
+	            System.arraycopy(m_providedServices, 0, newPS, 0, m_providedServices.length);
+	            newPS[m_providedServices.length] = ps;
+	            m_providedServices = newPS;
+	        }
+	        else { m_providedServices = new ProvidedService[] {ps}; }
+	}
+
+	/**
+	 * @return the component manager.
+	 */
+	public ComponentManager getComponentManager() { return m_componentManager; }
+
+	/**
+	 * @return the list of the provided service.
+	 */
+	public ProvidedService[] getProvidedService() { return m_providedServices; }
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+	 */
+	public void configure(ComponentManager cm, Element componentMetadata) {
+		// Fix the component managert & clean the provided service list
+		m_componentManager = cm;
+		m_providedServices = new ProvidedService[0];
+		// Create the dependency according to the component metadata
+		Element[] providedServices = componentMetadata.getElements("Provides");
+		for (int i = 0; i < providedServices.length; i++) {
+			// Create a ProvidedServiceMetadata object
+
+            // First : create the serviceSpecification array
+            String[] serviceSpecification = new String[0];
+            if (providedServices[i].containsAttribute("interface")) {
+                String serviceSpecificationStr = providedServices[i].getAttribute("interface");
+                //Get serviceSpecification if exist in the metadata
+                String[] spec = serviceSpecificationStr.split(",");
+                serviceSpecification = new String[spec.length];
+                for (int j = 0; j < spec.length; j++) { serviceSpecification[j] = spec[j].trim(); }
+            } else {
+            	Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+            	serviceSpecification = new String[manipulation.getElements("Interface").length];
+            	for (int j = 0; j < manipulation.getElements("Interface").length; j++) {
+            		serviceSpecification[j] = manipulation.getElements("Interface")[j].getAttribute("name");
+            	}
+            }
+
+            // Get the factory policy
+			int factory = ProvidedServiceMetadata.SINGLETON_FACTORY;
+			if (providedServices[i].containsAttribute("factory") && providedServices[i].getAttribute("factory").equals("service")) { factory = ProvidedService.SERVICE_FACTORY; }
+
+			// Then create the provided service metadata
+			ProvidedServiceMetadata psm = new ProvidedServiceMetadata(serviceSpecification, factory);
+
+			// Create properties
+			Element[] dynamicProps = providedServices[i].getElements("DynamicProperty");
+			Element[] staticProps = providedServices[i].getElements("StaticProperty");
+			Element[] props = providedServices[i].getElements("Property");
+			for (int j = 0; j < dynamicProps.length; j++) {
+				Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Please use property instead of dynamic property");
+				String name = null;
+				if (dynamicProps[j].containsAttribute("name")) { name = dynamicProps[j].getAttribute("name"); }
+				String field = dynamicProps[j].getAttribute("field");
+				String value = null;
+				if (dynamicProps[j].containsAttribute("value")) { value = dynamicProps[j].getAttribute("value"); }
+				String type = null;
+				if (dynamicProps[j].containsAttribute("type")) { type = dynamicProps[j].getAttribute("type"); }
+				PropertyMetadata pm = new PropertyMetadata(name, field, type, value);
+				psm.addProperty(pm);
+			}
+			for (int j = 0; j < staticProps.length; j++) {
+				Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Please use property instead of static property");
+				String name = staticProps[j].getAttribute("name");
+				String value = staticProps[j].getAttribute("value");
+				String type = staticProps[j].getAttribute("type");
+				PropertyMetadata pm = new PropertyMetadata(name, null, type, value);
+				psm.addProperty(pm);
+			}
+			for (int j = 0; j < props.length; j++) {
+				String name = null;
+				if (props[j].containsAttribute("name")) { name = props[j].getAttribute("name"); }
+				String value = null;
+				if (props[j].containsAttribute("value")) { value = props[j].getAttribute("value"); }
+				String type = null;
+				if (props[j].containsAttribute("type")) { type = props[j].getAttribute("type"); }
+				String field = null;
+				if (props[j].containsAttribute("field")) { field = props[j].getAttribute("field"); }
+				PropertyMetadata pm = new PropertyMetadata(name, field, type, value);
+				psm.addProperty(pm);
+			}
+
+			// Create the provided service object
+			ProvidedService ps = new ProvidedService(this, psm);
+			if (checkProvidedService(ps)) { addProvidedService(ps); }
+			else {
+                String itfs = "";
+                for (int j = 0; j < serviceSpecification.length; j++) {
+                    itfs = itfs + " " + serviceSpecification[j];
+                }
+				Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The provided service" + itfs + " is not valid, it will be removed");
+				ps = null;
+			}
+		}
+
+		if (providedServices.length > 0) { m_componentManager.register(this); }
+	}
+
+	private boolean containsInterface(String s) {
+		Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+		for (int i = 0; i < manipulation.getElements("Interface").length; i++) {
+			if (manipulation.getElements("Interface")[i].getAttribute("name").equals(s)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean checkProvidedService(ProvidedService ps) {
+
+        for (int i = 0; i < ps.getMetadata().getServiceSpecification().length; i++) {
+            if (!containsInterface(ps.getMetadata().getServiceSpecification()[i])) {
+                Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The service specification " + ps.getMetadata().getServiceSpecification()[i] + " is not implemented by the component class");
+                return false;
+            }
+        }
+
+		// Fix internal property type
+		for (int i = 0; i < ps.getProperties().length; i++) {
+			Property prop = ps.getProperties()[i];
+			String field = prop.getMetadata().getField();
+
+			if (field == null) {
+				// Static dependency -> Nothing to check
+				return true;
+			} else {
+				Element manipulation = getComponentManager().getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+	        	String type = null;
+	        	for (int j = 0; j < manipulation.getElements("Field").length; j++) {
+	        		if (field.equals(manipulation.getElements("Field")[j].getAttribute("name"))) {
+	        			type = manipulation.getElements("Field")[j].getAttribute("type");
+	        			break;
+	        		}
+	        	}
+				if (type == null) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] A declared property was not found in the class : " + prop.getMetadata().getField());
+					return false;
+				}
+
+				if (type != null) {
+					if (type.endsWith("[]")) {
+						// TODO array property
+						Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] An array property was found in the class [Not implemented yet] : " + prop.getMetadata().getField());
+						return false;
+					}
+
+					if (prop.getMetadata().getType() == null) { prop.getMetadata().setType(type); }
+
+					if (!prop.getMetadata().getType().equals(type)) {
+						Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The field type [" + type + "] and the declared type [" + prop.getMetadata().getType() + "] are not the same for " + prop.getMetadata().getField());
+						prop.getMetadata().setType(type);
+					}
+				}
+				else {
+					Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The declared property " + prop.getMetadata().getField() + "  does not exist in the code");
+				}
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Stop the provided service handler : unregister all provided services.
+	 * @see org.apache.felix.ipojo.Handler#stop()
+	 */
+	public void stop() {
+		for (int i = 0; i < m_providedServices.length; i++) {
+			m_providedServices[i].unregisterService();
+		}
+	}
+
+	/**
+	 * Start the provided service handler : register the service if the component is resolved.
+	 * Else do nothing and whait for a component state change event
+	 * @see org.apache.felix.ipojo.Handler#start()
+	 */
+	public void start() {
+		Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Start the provided service handler");
+			for (int i = 0; (m_componentManager.getState() == ComponentManager.VALID) && i < m_providedServices.length; i++) {
+				m_providedServices[i].registerService();
+			}
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+	 */
+	public void setterCallback(String fieldName, Object value) {
+		// Verify that the field name coreespond to a dependency
+		for (int i = 0; i < m_providedServices.length; i++) {
+			ProvidedService ps = m_providedServices[i];
+			for (int j = 0; j < ps.getProperties().length; j++) {
+				Property prop = ps.getProperties()[j];
+				if (fieldName.equals(prop.getMetadata().getField())) {
+					// it is the associated property
+					prop.set(value);
+				}
+			}
+		}
+		//Else do nothing
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+	 */
+	public Object getterCallback(String fieldName, Object value) {
+		for (int i = 0; i < m_providedServices.length; i++) {
+			ProvidedService ps = m_providedServices[i];
+			for (int j = 0; j < ps.getProperties().length; j++) {
+				Property prop = ps.getProperties()[j];
+				if (fieldName.equals(prop.getMetadata().getField())) {
+					// it is the associated property
+					return prop.get();
+				}
+			}
+		}
+		// Else it is not a property
+		return value;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#isValid()
+	 */
+	public boolean isValid() {
+		// The provided service handler does not need to manipulate the field
+		// Return always true
+		return true;
+	}
+
+	/**
+	 * Register the services if the new state is VALID.
+	 * Unregister the services if the new state is UNRESOLVED.
+	 * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+	 */
+	public void stateChanged(int state) {
+		// If the new state is UNRESOLVED => unregister all the services
+		if (state == ComponentManager.INVALID) {
+			stop();
+			return;
+		}
+
+		// If the new state is VALID => regiter all the services
+		if (state == ComponentManager.VALID) {
+			start();
+			return;
+		}
+
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceMetadata.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceMetadata.java
new file mode 100644
index 0000000..a4e7fd3
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceMetadata.java
@@ -0,0 +1,108 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+
+/**
+ * Provided Service Metadata.
+ * @author Clément Escoffier
+ */
+public class ProvidedServiceMetadata {
+
+	 /**
+     * Factory Policy : SINGLETON_FACTORY.
+     */
+    public static final int SINGLETON_FACTORY = 0;
+
+    /**
+     * Factory policy : SERVICE_FACTORY.
+     */
+    public static final int SERVICE_FACTORY = 1;
+
+    /**
+     * Factory policy : COMPONENT_FACTORY.
+     * TODO : Component_factory behavior
+     */
+    public static final int COMPONENT_FACTORY = 2;
+
+	/**
+	 * At this time, it is only the java interface full name.
+	 */
+	private String[] m_serviceSpecification = new String[0];
+
+	/**
+	 * List of proeprty metadata.
+	 */
+	private PropertyMetadata[] m_properties = new PropertyMetadata[0];
+
+	/**
+	 * Foactory policy.
+	 */
+	private int m_factoryPolicy = SINGLETON_FACTORY;
+
+	//CONSTRUCTOR :
+
+	/**
+     * Constructor.
+	 * @param specification : service specification (i.e. the interface)
+	 * @param factoryPolicy : the facotry policy.
+	 */
+	public ProvidedServiceMetadata(String[] specification, int factoryPolicy) {
+		m_serviceSpecification = specification;
+		m_factoryPolicy = factoryPolicy;
+	}
+
+	// GETTERS :
+
+
+	/**
+	 * @return the service specification (i.e. the interface)
+	 */
+	public String[] getServiceSpecification() { return m_serviceSpecification; }
+
+	/**
+	 * @return the property metadata list.
+	 */
+	public PropertyMetadata[] getProperties() { return m_properties; }
+
+	/**
+	 * @return the factory policy.
+	 */
+	public int getFactoryPolicy() { return m_factoryPolicy; }
+
+	// SETTERS  :
+
+	/**
+     * Add the given property metadata to the property metadata list.
+	 * @param p : property metdata to add
+	 */
+	protected void addProperty(PropertyMetadata p) {
+        for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
+            if (m_properties[i] == p) { return; }
+        }
+
+        if (m_properties.length > 0) {
+            PropertyMetadata[] newProp = new PropertyMetadata[m_properties.length + 1];
+            System.arraycopy(m_properties, 0, newProp, 0, m_properties.length);
+            newProp[m_properties.length] = p;
+            m_properties = newProp;
+        }
+        else {
+        	m_properties = new PropertyMetadata[] {p};
+        }
+	}
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
new file mode 100644
index 0000000..b7171e6
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
@@ -0,0 +1,180 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.parser;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Manifest Metadata parser.
+ * Read a manifest file and construct metadata
+ * @author Clement Escoffier
+ */
+public class ManifestMetadataParser {
+
+	/**
+	 * Manifest Headers.
+	 */
+	private Dictionary m_headers;
+
+	/**
+	 * Element list.
+	 */
+	private Element[] m_elements = new Element[0];
+
+    /**
+     * @return the component metadata.
+     * @throws ParseException when a parsing error occurs
+     */
+    public Element[] getComponentsMetadata() throws ParseException {
+    	return m_elements[0].getElements("Component");
+    }
+
+    private void addElement(Element elem) {
+    	for (int i = 0; (m_elements != null) && (i < m_elements.length); i++) {
+            if (m_elements[i] == elem) { return; }
+        }
+
+        if (m_elements != null) {
+            Element[] newElementsList = new Element[m_elements.length + 1];
+            System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
+            newElementsList[m_elements.length] = elem;
+            m_elements = newElementsList;
+        }
+        else { m_elements = new Element[] {elem}; }
+	}
+
+    private Element removeLastElement() {
+		int idx = -1;
+		idx = m_elements.length - 1;
+		Element last = m_elements[idx];
+        if (idx >= 0) {
+            if ((m_elements.length - 1) == 0) {
+            	// It is the last element of the list;
+            	m_elements = new Element[0];
+            	}
+            else {
+            	// Remove the last element of the list :
+                Element[] newElementsList = new Element[m_elements.length - 1];
+                System.arraycopy(m_elements, 0, newElementsList, 0, idx);
+                m_elements = newElementsList;
+            }
+        }
+        return last;
+	}
+
+	/**
+	 * Parse the given dictionnary and create the components manager.
+	 * @param dict : the given headers of the manifest file
+	 * @throws ParseException : if any error occurs
+	 */
+	public void parse(Dictionary dict) throws ParseException {
+		m_headers = dict;
+		String componentClassesStr = (String)m_headers.get("iPOJO-Components");
+		//Add the ipojo element inside the element list
+		addElement(new Element("iPOJO", ""));
+		parseElements(componentClassesStr.trim());
+
+	}
+
+	/**
+	 * Parse the metadata from the string given in argument.
+	 * @param metadata : the metadata to parse
+	 * @return Element : the root element resulting of the parsing
+	 * @throws ParseException : if any error occurs
+	 */
+	public static Element parse(String metadata) throws ParseException  {
+		ManifestMetadataParser parser = new ManifestMetadataParser();
+		parser.parseElements(metadata);
+		if (parser.m_elements.length != 1) { throw new ParseException("Error in parsing, root element not found : " + metadata); }
+		return parser.m_elements[0];
+	}
+
+	private void parseElements(String s) {
+		char[] string = s.toCharArray();
+
+		for (int i = 0; i < string.length; i++) {
+			char c = string[i];
+
+			switch(c) {
+
+			case '$' :
+				String attName = "";
+				String attValue = "";
+				String attNs = "";
+				i++;
+				c = string[i];
+				while (c != '=') {
+					if (c == ':') {
+						attNs = attName;
+						attName = "";
+					} else { attName = attName + c; }
+					i = i + 1;
+					c = string[i];
+				}
+				i++; // skip =
+				c = string[i];
+				while (c != ' ') {
+					attValue = attValue + c;
+					i++;
+					c = string[i];
+				}
+				Attribute att = new Attribute(attName, attNs , attValue);
+				m_elements[m_elements.length - 1].addAttribute(att);
+				break;
+
+			case '}' :
+				Element lastElement = removeLastElement();
+				if (m_elements.length != 0) {
+					Element newQueue = m_elements[m_elements.length - 1];
+					newQueue.addElement(lastElement);
+				}
+				else {
+					addElement(lastElement);
+				}
+				break;
+			case ' ' : break; // do nothing;
+			default :
+					String name = "";
+					String ns = "";
+					c = string[i];
+					while (c != ' ') {
+						if (c == ':') {
+							ns = name;
+							name = "";
+							i++;
+							c = string[i];
+						}
+						else {
+							name = name + c;
+							i++;
+							c = string[i];
+						}
+					}
+					// Skip spaces
+					while (string[i] == ' ') { i = i + 1; }
+					i = i + 1; // skip {
+				    Element elem = new Element(name, ns);
+					addElement(elem);
+				break;
+			}
+			}
+		}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseException.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseException.java
new file mode 100644
index 0000000..4cf61b8
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseException.java
@@ -0,0 +1,38 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.parser;
+
+/**
+ * Exceptions thrown by parsers.
+ * @author Clement Escoffier
+ */
+public class ParseException extends Exception {
+
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Parsing error.
+     * @param msg : the error emssage.
+     */
+    public ParseException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/Configuration.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/Configuration.java
new file mode 100644
index 0000000..a4d54cd
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/Configuration.java
@@ -0,0 +1,227 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/Configuration.java,v 1.16 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.cm;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+/**
+ * The configuration information for a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code> object.
+ * 
+ * The Configuration Admin service uses this interface to represent the
+ * configuration information for a <code>ManagedService</code> or for a
+ * service instance of a <code>ManagedServiceFactory</code>.
+ * 
+ * <p>
+ * A <code>Configuration</code> object contains a configuration dictionary and
+ * allows the properties to be updated via this object. Bundles wishing to
+ * receive configuration dictionaries do not need to use this class - they
+ * register a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code>. Only administrative bundles, and
+ * bundles wishing to update their own configurations need to use this class.
+ * 
+ * <p>
+ * The properties handled in this configuration have case insensitive
+ * <code>String</code> objects as keys. However, case is preserved from the
+ * last set key/value.
+ * <p>
+ * A configuration can be <i>bound </i> to a bundle location (
+ * <code>Bundle.getLocation()</code>). The purpose of binding a
+ * <code>Configuration</code> object to a location is to make it impossible
+ * for another bundle to forge a PID that would match this configuration. When a
+ * configuration is bound to a specific location, and a bundle with a different
+ * location registers a corresponding <code>ManagedService</code> object or
+ * <code>ManagedServiceFactory</code> object, then the configuration is not
+ * passed to the updated method of that object.
+ * 
+ * <p>
+ * If a configuration's location is <code>null</code>, it is not yet bound to
+ * a location. It will become bound to the location of the first bundle that
+ * registers a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code> object with the corresponding PID.
+ * <p>
+ * The same <code>Configuration</code> object is used for configuring both a
+ * Managed Service Factory and a Managed Service. When it is important to
+ * differentiate between these two the term "factory configuration" is used.
+ * 
+ * @version $Revision: 1.16 $
+ */
+public interface Configuration {
+	/**
+	 * Get the PID for this <code>Configuration</code> object.
+	 * 
+	 * @return the PID for this <code>Configuration</code> object.
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public String getPid();
+
+	/**
+	 * Return the properties of this <code>Configuration</code> object.
+	 * 
+	 * The <code>Dictionary</code> object returned is a private copy for the
+	 * caller and may be changed without influencing the stored configuration.
+	 * The keys in the returned dictionary are case insensitive and are always
+	 * of type <code>String</code>.
+	 * 
+	 * <p>
+	 * If called just after the configuration is created and before update has
+	 * been called, this method returns <code>null</code>.
+	 * 
+	 * @return A private copy of the properties for the caller or
+	 *         <code>null</code>. These properties must not contain the
+	 *         "service.bundleLocation" property. The value of this property may
+	 *         be obtained from the <code>getBundleLocation</code> method.
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public Dictionary getProperties();
+
+	/**
+	 * Update the properties of this <code>Configuration</code> object.
+	 * 
+	 * Stores the properties in persistent storage after adding or overwriting
+	 * the following properties:
+	 * <ul>
+	 * <li>"service.pid" : is set to be the PID of this configuration.</li>
+	 * <li>"service.factoryPid" : if this is a factory configuration it is set
+	 * to the factory PID else it is not set.</li>
+	 * </ul>
+	 * These system properties are all of type <code>String</code>.
+	 * 
+	 * <p>
+	 * If the corresponding Managed Service/Managed Service Factory is
+	 * registered, its updated method must be called asynchronously. Else, this
+	 * callback is delayed until aforementioned registration occurs.
+	 * 
+	 * <p>
+	 * Also intiates an asynchronous call to all
+	 * <code>ConfigurationListener</code>s with a
+	 * <code>ConfigurationEvent.CM_UPDATED</code> event.
+	 * 
+	 * @param properties the new set of properties for this configuration
+	 * @throws IOException if update cannot be made persistent
+	 * @throws IllegalArgumentException if the <code>Dictionary</code> object
+	 *         contains invalid configuration types or contains case variants of
+	 *         the same key name.
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public void update(Dictionary properties) throws IOException;
+
+	/**
+	 * Delete this <code>Configuration</code> object.
+	 * 
+	 * Removes this configuration object from the persistent store. Notify
+	 * asynchronously the corresponding Managed Service or Managed Service
+	 * Factory. A <code>ManagedService</code> object is notified by a call to
+	 * its <code>updated</code> method with a <code>null</code> properties
+	 * argument. A <code>ManagedServiceFactory</code> object is notified by a
+	 * call to its <code>deleted</code> method.
+	 * 
+	 * <p>
+	 * Also intiates an asynchronous call to all
+	 * <code>ConfigurationListener</code>s with a
+	 * <code>ConfigurationEvent.CM_DELETED</code> event.
+	 * 
+	 * @throws IOException If delete fails
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public void delete() throws IOException;
+
+	/**
+	 * For a factory configuration return the PID of the corresponding Managed
+	 * Service Factory, else return <code>null</code>.
+	 * 
+	 * @return factory PID or <code>null</code>
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public String getFactoryPid();
+
+	/**
+	 * Update the <code>Configuration</code> object with the current
+	 * properties.
+	 * 
+	 * Initiate the <code>updated</code> callback to the Managed Service or
+	 * Managed Service Factory with the current properties asynchronously.
+	 * 
+	 * <p>
+	 * This is the only way for a bundle that uses a Configuration Plugin
+	 * service to initate a callback. For example, when that bundle detects a
+	 * change that requires an update of the Managed Service or Managed Service
+	 * Factory via its <code>ConfigurationPlugin</code> object.
+	 * 
+	 * @see ConfigurationPlugin
+	 * @throws IOException if update cannot access the properties in persistent
+	 *         storage
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public void update() throws IOException;
+
+	/**
+	 * Bind this <code>Configuration</code> object to the specified bundle
+	 * location.
+	 * 
+	 * If the bundleLocation parameter is <code>null</code> then the
+	 * <code>Configuration</code> object will not be bound to a location. It
+	 * will be set to the bundle's location before the first time a Managed
+	 * Service/Managed Service Factory receives this <code>Configuration</code>
+	 * object via the updated method and before any plugins are called. The
+	 * bundle location will be set persistently.
+	 * 
+	 * @param bundleLocation a bundle location or <code>null</code>
+	 * @throws IllegalStateException If this configuration has been deleted.
+	 * @throws SecurityException If the caller does not have
+	 *         <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public void setBundleLocation(String bundleLocation);
+
+	/**
+	 * Get the bundle location.
+	 * 
+	 * Returns the bundle location to which this configuration is bound, or
+	 * <code>null</code> if it is not yet bound to a bundle location.
+	 * 
+	 * @return location to which this configuration is bound, or
+	 *         <code>null</code>.
+	 * @throws IllegalStateException If this <code>Configuration</code> object
+	 *         has been deleted.
+	 * @throws SecurityException If the caller does not have
+	 *         <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public String getBundleLocation();
+
+	/**
+	 * Equality is defined to have equal PIDs
+	 * 
+	 * Two Configuration objects are equal when their PIDs are equal.
+	 * 
+	 * @param other <code>Configuration</code> object to compare against
+	 * @return <code>true</code> if equal, <code>false</code> if not a
+	 *         <code>Configuration</code> object or one with a different PID.
+	 */
+	public boolean equals(Object other);
+
+	/**
+	 * Hash code is based on PID.
+	 * 
+	 * The hashcode for two Configuration objects must be the same when the
+	 * Configuration PID's are the same.
+	 * 
+	 * @return hash code for this Configuration object
+	 */
+	public int hashCode();
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
new file mode 100644
index 0000000..f0f7836
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
@@ -0,0 +1,256 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationAdmin.java,v 1.14 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.cm;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Service for administering configuration data.
+ * 
+ * <p>
+ * The main purpose of this interface is to store bundle configuration data
+ * persistently. This information is represented in <code>Configuration</code>
+ * objects. The actual configuration data is a <code>Dictionary</code> of
+ * properties inside a <code>Configuration</code> object.
+ * 
+ * <p>
+ * There are two principally different ways to manage configurations. First
+ * there is the concept of a Managed Service, where configuration data is
+ * uniquely associated with an object registered with the service registry.
+ * 
+ * <p>
+ * Next, there is the concept of a factory where the Configuration Admin service
+ * will maintain 0 or more <code>Configuration</code> objects for a Managed
+ * Service Factory that is registered with the Framework.
+ * 
+ * <p>
+ * The first concept is intended for configuration data about "things/services"
+ * whose existence is defined externally, e.g. a specific printer. Factories are
+ * intended for "things/services" that can be created any number of times, e.g.
+ * a configuration for a DHCP server for different networks.
+ * 
+ * <p>
+ * Bundles that require configuration should register a Managed Service or a
+ * Managed Service Factory in the service registry. A registration property
+ * named <code>service.pid</code> (persistent identifier or PID) must be used
+ * to identify this Managed Service or Managed Service Factory to the
+ * Configuration Admin service.
+ * 
+ * <p>
+ * When the ConfigurationAdmin detects the registration of a Managed Service, it
+ * checks its persistent storage for a configuration object whose PID matches
+ * the PID registration property (<code>service.pid</code>) of the Managed
+ * Service. If found, it calls {@link ManagedService#updated}method with the
+ * new properties. The implementation of a Configuration Admin service must run
+ * these call-backs asynchronously to allow proper synchronization.
+ * 
+ * <p>
+ * When the Configuration Admin service detects a Managed Service Factory
+ * registration, it checks its storage for configuration objects whose
+ * <code>factoryPid</code> matches the PID of the Managed Service Factory. For
+ * each such <code>Configuration</code> objects, it calls the
+ * <code>ManagedServiceFactory.updated</code> method asynchronously with the
+ * new properties. The calls to the <code>updated</code> method of a
+ * <code>ManagedServiceFactory</code> must be executed sequentially and not
+ * overlap in time.
+ * 
+ * <p>
+ * In general, bundles having permission to use the Configuration Admin service
+ * can only access and modify their own configuration information. Accessing or
+ * modifying the configuration of another bundle requires
+ * <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ * 
+ * <p>
+ * <code>Configuration</code> objects can be <i>bound </i> to a specified
+ * bundle location. In this case, if a matching Managed Service or Managed
+ * Service Factory is registered by a bundle with a different location, then the
+ * Configuration Admin service must not do the normal callback, and it should
+ * log an error. In the case where a <code>Configuration</code> object is not
+ * bound, its location field is <code>null</code>, the Configuration Admin
+ * service will bind it to the location of the bundle that registers the first
+ * Managed Service or Managed Service Factory that has a corresponding PID
+ * property. When a <code>Configuration</code> object is bound to a bundle
+ * location in this manner, the Confguration Admin service must detect if the
+ * bundle corresponding to the location is uninstalled. If this occurs, the
+ * <code>Configuration</code> object is unbound, that is its location field is
+ * set back to <code>null</code>.
+ * 
+ * <p>
+ * The method descriptions of this class refer to a concept of "the calling
+ * bundle". This is a loose way of referring to the bundle which obtained the
+ * Configuration Admin service from the service registry. Implementations of
+ * <code>ConfigurationAdmin</code> must use a
+ * {@link org.osgi.framework.ServiceFactory}to support this concept.
+ * 
+ * @version $Revision: 1.14 $
+ */
+public interface ConfigurationAdmin {
+	/**
+	 * Service property naming the Factory PID in the configuration dictionary.
+	 * The property's value is of type <code>String</code>.
+	 * 
+	 * @since 1.1
+	 */
+	public final static String	SERVICE_FACTORYPID		= "service.factoryPid";
+	/**
+	 * Service property naming the location of the bundle that is associated
+	 * with a a <code>Configuration</code> object. This property can be
+	 * searched for but must not appear in the configuration dictionary for
+	 * security reason. The property's value is of type <code>String</code>.
+	 * 
+	 * @since 1.1
+	 */
+	public final static String	SERVICE_BUNDLELOCATION	= "service.bundleLocation";
+
+	/**
+	 * Create a new factory <code>Configuration</code> object with a new PID.
+	 * 
+	 * The properties of the new <code>Configuration</code> object are
+	 * <code>null</code> until the first time that its
+	 * {@link Configuration#update(Dictionary)}method is called.
+	 * 
+	 * <p>
+	 * It is not required that the <code>factoryPid</code> maps to a
+	 * registered Managed Service Factory.
+	 * <p>
+	 * The <code>Configuration</code> object is bound to the location of the
+	 * calling bundle.
+	 * 
+	 * @param factoryPid PID of factory (not <code>null</code>).
+	 * @return A new <code>Configuration</code> object.
+	 * @throws IOException if access to persistent storage fails.
+	 * @throws SecurityException if caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code> and <code>factoryPid</code> is bound to another bundle.
+	 */
+	public Configuration createFactoryConfiguration(String factoryPid)
+			throws IOException;
+
+	/**
+	 * Create a new factory <code>Configuration</code> object with a new PID.
+	 * 
+	 * The properties of the new <code>Configuration</code> object are
+	 * <code>null</code> until the first time that its
+	 * {@link Configuration#update(Dictionary)}method is called.
+	 * 
+	 * <p>
+	 * It is not required that the <code>factoryPid</code> maps to a
+	 * registered Managed Service Factory.
+	 * 
+	 * <p>
+	 * The <code>Configuration</code> is bound to the location specified. If
+	 * this location is <code>null</code> it will be bound to the location of
+	 * the first bundle that registers a Managed Service Factory with a
+	 * corresponding PID.
+	 * 
+	 * @param factoryPid PID of factory (not <code>null</code>).
+	 * @param location A bundle location string, or <code>null</code>.
+	 * @return a new <code>Configuration</code> object.
+	 * @throws IOException if access to persistent storage fails.
+	 * @throws SecurityException if caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public Configuration createFactoryConfiguration(String factoryPid, String location)
+			throws IOException;
+
+	/**
+	 * Get an existing <code>Configuration</code> object from the persistent
+	 * store, or create a new <code>Configuration</code> object.
+	 * 
+	 * <p>
+	 * If a <code>Configuration</code> with this PID already exists in
+	 * Configuration Admin service return it. The location parameter is ignored
+	 * in this case.
+	 * 
+	 * <p>
+	 * Else, return a new <code>Configuration</code> object. This new object
+	 * is bound to the location and the properties are set to <code>null</code>.
+	 * If the location parameter is <code>null</code>, it will be set when a
+	 * Managed Service with the corresponding PID is registered for the first
+	 * time.
+	 * 
+	 * @param pid Persistent identifier.
+	 * @param location The bundle location string, or <code>null</code>.
+	 * @return An existing or new <code>Configuration</code> object.
+	 * @throws IOException if access to persistent storage fails.
+	 * @throws SecurityException if the caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public Configuration getConfiguration(String pid, String location)
+			throws IOException;
+
+	/**
+	 * Get an existing or new <code>Configuration</code> object from the
+	 * persistent store.
+	 * 
+	 * If the <code>Configuration</code> object for this PID does not exist,
+	 * create a new <code>Configuration</code> object for that PID, where
+	 * properties are <code>null</code>. Bind its location to the calling
+	 * bundle's location.
+	 * 
+	 * <p>
+	 * Otherwise, if the location of the existing <code>Configuration</code> object
+	 * is <code>null</code>, set it to the calling bundle's location.
+	 * 
+	 * @param pid persistent identifier.
+	 * @return an existing or new <code>Configuration</code> matching the PID.
+	 * @throws IOException if access to persistent storage fails.
+	 * @throws SecurityException if the <code>Configuration</code> object is bound to a location different from that of the calling bundle and it has no <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public Configuration getConfiguration(String pid) throws IOException;
+
+	/**
+	 * List the current <code>Configuration</code> objects which match the
+	 * filter.
+	 * 
+	 * <p>
+	 * Only <code>Configuration</code> objects with non- <code>null</code>
+	 * properties are considered current. That is,
+	 * <code>Configuration.getProperties()</code> is guaranteed not to return
+	 * <code>null</code> for each of the returned <code>Configuration</code>
+	 * objects.
+	 * 
+	 * <p>
+	 * Normally only <code>Configuration</code> objects that are bound to the
+	 * location of the calling bundle are returned, or all if the caller has 
+	 * <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 * 
+	 * <p>
+	 * The syntax of the filter string is as defined in the <code>Filter</code>
+	 * class. The filter can test any configuration parameters including the
+	 * following system properties:
+	 * <ul>
+	 * <li><code>service.pid</code>-<code>String</code>- the PID under
+	 * which this is registered</li>
+	 * <li><code>service.factoryPid</code>-<code>String</code>- the
+	 * factory if applicable</li>
+	 * <li><code>service.bundleLocation</code>-<code>String</code>- the
+	 * bundle location</li>
+	 * </ul>
+	 * The filter can also be <code>null</code>, meaning that all
+	 * <code>Configuration</code> objects should be returned.
+	 * 
+	 * @param filter a <code>Filter</code> object, or <code>null</code> to
+	 *        retrieve all <code>Configuration</code> objects.
+	 * @return all matching <code>Configuration</code> objects, or
+	 *         <code>null</code> if there aren't any
+	 * @throws IOException if access to persistent storage fails
+	 * @throws InvalidSyntaxException if the filter string is invalid
+	 */
+	public Configuration[] listConfigurations(String filter) throws IOException,
+			InvalidSyntaxException;
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationEvent.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
new file mode 100644
index 0000000..28ef9e4
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
@@ -0,0 +1,167 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationEvent.java,v 1.8 2006/03/14 01:21:09 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.service.cm;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A Configuration Event.
+ * 
+ * <p>
+ * <code>ConfigurationEvent</code> objects are delivered to all registered
+ * <code>ConfigurationListener</code> service objects. ConfigurationEvents
+ * must be asynchronously delivered in chronological order with respect to each
+ * listener.
+ * 
+ * <p>
+ * A type code is used to identify the type of event. The following event types
+ * are defined:
+ * <ul>
+ * <li>{@link #CM_UPDATED}
+ * <li>{@link #CM_DELETED}
+ * </ul>
+ * Additional event types may be defined in the future.
+ * 
+ * <p>
+ * Security Considerations. <code>ConfigurationEvent</code> objects do not
+ * provide <code>Configuration</code> objects, so no sensitive configuration
+ * information is available from the event. If the listener wants to locate the
+ * <code>Configuration</code> object for the specified pid, it must use
+ * <code>ConfigurationAdmin</code>.
+ * 
+ * @see ConfigurationListener
+ * 
+ * @version $Revision: 1.8 $
+ * @since 1.2
+ */
+public class ConfigurationEvent {
+	/**
+	 * A <code>Configuration</code> has been updated.
+	 * 
+	 * <p>
+	 * This <code>ConfigurationEvent</code> type that indicates that a
+	 * <code>Configuration</code> object has been updated with new properties.
+	 * 
+	 * An event is fired when a call to <code>Configuration.update</code>
+	 * successfully changes a configuration.
+	 * 
+	 * <p>
+	 * The value of <code>CM_UPDATED</code> is 1.
+	 */
+	public static final int			CM_UPDATED	= 1;
+	/**
+	 * A <code>Configuration</code> has been deleted.
+	 * 
+	 * <p>
+	 * This <code>ConfigurationEvent</code> type that indicates that a
+	 * <code>Configuration</code> object has been deleted.
+	 * 
+	 * An event is fired when a call to <code>Configuration.delete</code>
+	 * successfully deletes a configuration.
+	 * 
+	 * <p>
+	 * The value of <code>CM_DELETED</code> is 2.
+	 */
+	public static final int			CM_DELETED	= 2;
+	/**
+	 * Type of this event.
+	 * 
+	 * @see #getType
+	 */
+	private final int				type;
+	/**
+	 * The factory pid associated with this event.
+	 */
+	private final String			factoryPid;
+	/**
+	 * The pid associated with this event.
+	 */
+	private final String			pid;
+	/**
+	 * The ConfigurationAdmin service which created this event.
+	 */
+	private final ServiceReference	reference;
+
+	/**
+	 * Constructs a <code>ConfigurationEvent</code> object from the given
+	 * <code>ServiceReference</code> object, event type, and pids.
+	 * 
+	 * @param reference The <code>ServiceReference</code> object of the
+	 *        Configuration Admin service that created this event.
+	 * @param type The event type. See {@link #getType}.
+	 * @param factoryPid The factory pid of the associated configuration if the
+	 *        target of the configuration is a ManagedServiceFactory. Otherwise
+	 *        <code>null</code> if the target of the configuration is a
+	 *        ManagedService.
+	 * @param pid The pid of the associated configuration.
+	 */
+	public ConfigurationEvent(ServiceReference reference, int type,
+			String factoryPid, String pid) {
+		this.reference = reference;
+		this.type = type;
+		this.factoryPid = factoryPid;
+		this.pid = pid;
+	}
+
+	/**
+	 * Returns the factory pid of the associated configuration.
+	 * 
+	 * @return Returns the factory pid of the associated configuration if the
+	 *         target of the configuration is a ManagedServiceFactory. Otherwise
+	 *         <code>null</code> if the target of the configuration is a
+	 *         ManagedService.
+	 */
+	public String getFactoryPid() {
+		return factoryPid;
+	}
+
+	/**
+	 * Returns the pid of the associated configuration.
+	 * 
+	 * @return Returns the pid of the associated configuration.
+	 */
+	public String getPid() {
+		return pid;
+	}
+
+	/**
+	 * Return the type of this event.
+	 * <p>
+	 * The type values are:
+	 * <ul>
+	 * <li>{@link #CM_UPDATED}
+	 * <li>{@link #CM_DELETED}
+	 * </ul>
+	 * 
+	 * @return The type of this event.
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/**
+	 * Return the <code>ServiceReference</code> object of the Configuration
+	 * Admin service that created this event.
+	 * 
+	 * @return The <code>ServiceReference</code> object for the Configuration
+	 *         Admin service that created this event.
+	 */
+	public ServiceReference getReference() {
+		return reference;
+	}
+}
\ No newline at end of file
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationException.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationException.java
new file mode 100644
index 0000000..6d41dce
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationException.java
@@ -0,0 +1,112 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationException.java,v 1.11 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.cm;
+
+/**
+ * An <code>Exception</code> class to inform the Configuration Admin service
+ * of problems with configuration data.
+ * 
+ * @version $Revision: 1.11 $
+ */
+public class ConfigurationException extends Exception {
+	static final long	serialVersionUID	= -1690090413441769377L;
+
+	private String		property;
+	private String		reason;
+
+	/**
+	 * Nested exception.
+	 */
+	private Throwable	cause;
+
+	/**
+	 * Create a <code>ConfigurationException</code> object.
+	 * 
+	 * @param property name of the property that caused the problem,
+	 *        <code>null</code> if no specific property was the cause
+	 * @param reason reason for failure
+	 */
+	public ConfigurationException(String property, String reason) {
+		super(property + " : " + reason);
+		this.property = property;
+		this.reason = reason;
+		this.cause = null;
+	}
+
+	/**
+	 * Create a <code>ConfigurationException</code> object.
+	 * 
+	 * @param property name of the property that caused the problem,
+	 *        <code>null</code> if no specific property was the cause
+	 * @param reason reason for failure
+	 * @param cause The cause of this exception.
+	 * @since 1.2
+	 */
+	public ConfigurationException(String property, String reason,
+			Throwable cause) {
+		super(property + " : " + reason);
+		this.property = property;
+		this.reason = reason;
+		this.cause = cause;
+	}
+
+	/**
+	 * Return the property name that caused the failure or null.
+	 * 
+	 * @return name of property or null if no specific property caused the
+	 *         problem
+	 */
+	public String getProperty() {
+		return property;
+	}
+
+	/**
+	 * Return the reason for this exception.
+	 * 
+	 * @return reason of the failure
+	 */
+	public String getReason() {
+		return reason;
+	}
+
+	/**
+	 * Returns the cause of this exception or <code>null</code> if no cause
+	 * was specified when this exception was created.
+	 * 
+	 * @return The cause of this exception or <code>null</code> if no cause
+	 *         was specified.
+	 * @since 1.2
+	 */
+	public Throwable getCause() {
+		return cause;
+	}
+
+	/**
+	 * The cause of this exception can only be set when constructed.
+	 * 
+	 * @param cause Cause of the exception.
+	 * @return This object.
+	 * @throws java.lang.IllegalStateException This method will always throw an
+	 *         <code>IllegalStateException</code> since the cause of this
+	 *         exception can only be set when constructed.
+	 * @since 1.2
+	 */
+	public Throwable initCause(Throwable cause) {
+		throw new IllegalStateException();
+	}
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationListener.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationListener.java
new file mode 100644
index 0000000..f7fb6a6
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationListener.java
@@ -0,0 +1,50 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationListener.java,v 1.9 2006/03/14 01:21:09 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.service.cm;
+
+/**
+ * Listener for Configuration Events. When a <code>ConfigurationEvent</code>
+ * is fired, it is asynchronously delivered to a
+ * <code>ConfigurationListener</code>.
+ * 
+ * <p>
+ * <code>ConfigurationListener</code> objects are registered with the
+ * Framework service registry and are notified with a
+ * <code>ConfigurationEvent</code> object when an event is fired.
+ * <p>
+ * <code>ConfigurationListener</code> objects can inspect the received
+ * <code>ConfigurationEvent</code> object to determine its type, the pid of
+ * the <code>Configuration</code> object with which it is associated, and the
+ * Configuration Admin service that fired the event.
+ * 
+ * <p>
+ * Security Considerations. Bundles wishing to monitor configuration events will
+ * require <code>ServicePermission[ConfigurationListener,REGISTER]</code> to
+ * register a <code>ConfigurationListener</code> service.
+ * 
+ * @version $Revision: 1.9 $
+ * @since 1.2
+ */
+public interface ConfigurationListener {
+	/**
+	 * Receives notification of a Configuration that has changed.
+	 * 
+	 * @param event The <code>ConfigurationEvent</code>.
+	 */
+	public void configurationEvent(ConfigurationEvent event);
+}
\ No newline at end of file
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
new file mode 100644
index 0000000..dc0c6ec
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
@@ -0,0 +1,217 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationPermission.java,v 1.20 2006/03/14 01:21:09 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.service.cm;
+
+import java.security.*;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * Indicates a bundle's authority to configure bundles.
+ * 
+ * This permission has only a single action: CONFIGURE.
+ * 
+ * @version $Revision: 1.20 $
+ * @since 1.2
+ */
+
+public final class ConfigurationPermission extends BasicPermission {
+	static final long			serialVersionUID	= 5716868734811965383L;
+	/**
+	 * The action string <code>configure</code>.
+	 */
+	public final static String	CONFIGURE			= "configure";
+
+	/**
+	 * Create a new ConfigurationPermission.
+	 * 
+	 * @param name Name must be &quot;*&quot;.
+	 * @param actions <code>configure</code> (canonical order).
+	 */
+
+	public ConfigurationPermission(String name, String actions) {
+		super(name);
+		if (!name.equals("*")) {
+			throw new IllegalArgumentException("name must be *");
+		}
+		actions = actions.trim();
+		if (actions.equalsIgnoreCase(CONFIGURE)||actions.equals("*"))
+			return;
+		
+		throw new IllegalArgumentException("actions must be " + CONFIGURE);
+	}
+
+	/**
+	 * Determines if a <code>ConfigurationPermission</code> object "implies"
+	 * the specified permission.
+	 * 
+	 * @param p The target permission to check.
+	 * @return <code>true</code> if the specified permission is implied by
+	 *         this object; <code>false</code> otherwise.
+	 */
+
+	public boolean implies(Permission p) {
+		return p instanceof ConfigurationPermission;
+	}
+
+	/**
+	 * Determines the equality of two <code>ConfigurationPermission</code>
+	 * objects.
+	 * <p>
+	 * Two <code>ConfigurationPermission</code> objects are equal.
+	 * 
+	 * @param obj The object being compared for equality with this object.
+	 * @return <code>true</code> if <code>obj</code> is equivalent to this
+	 *         <code>ConfigurationPermission</code>; <code>false</code>
+	 *         otherwise.
+	 */
+	public boolean equals(Object obj) {
+		return obj instanceof ConfigurationPermission;
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return Hash code value for this object.
+	 */
+
+	public int hashCode() {
+		return getName().hashCode() ^ getActions().hashCode();
+	}
+
+	/**
+	 * Returns the canonical string representation of the
+	 * <code>ConfigurationPermission</code> actions.
+	 * 
+	 * <p>
+	 * Always returns present <code>ConfigurationPermission</code> actions in
+	 * the following order: <code>CONFIGURE</code>
+	 * 
+	 * @return Canonical string representation of the
+	 *         <code>ConfigurationPermission</code> actions.
+	 */
+	public String getActions() {
+		return CONFIGURE;
+	}
+
+	/**
+	 * Returns a new <code>PermissionCollection</code> object suitable for
+	 * storing <code>ConfigurationPermission</code>s.
+	 * 
+	 * @return A new <code>PermissionCollection</code> object.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new ConfigurationPermissionCollection();
+	}
+}
+
+/**
+ * Stores a set of <code>ConfigurationPermission</code> permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+final class ConfigurationPermissionCollection extends PermissionCollection {
+	static final long	serialVersionUID	= -6917638867081695839L;
+	/**
+	 * True if collection is non-empty.
+	 * 
+	 * @serial
+	 */
+	private boolean		hasElement;
+
+	/**
+	 * Creates an empty <tt>ConfigurationPermissionCollection</tt> object.
+	 * 
+	 */
+	public ConfigurationPermissionCollection() {
+		hasElement = false;
+	}
+
+	/**
+	 * Adds the specified permission to the
+	 * <tt>ConfigurationPermissionCollection</tt>. The key for the hash is
+	 * the interface name of the service.
+	 * 
+	 * @param permission The <tt>Permission</tt> object to add.
+	 * 
+	 * @exception IllegalArgumentException If the permission is not an
+	 *            <tt>ConfigurationPermission</tt>.
+	 * 
+	 * @exception SecurityException If this ConfigurationPermissionCollection
+	 *            object has been marked read-only.
+	 */
+
+	public void add(Permission permission) {
+		if (!(permission instanceof ConfigurationPermission)) {
+			throw new IllegalArgumentException("invalid permission: "
+					+ permission);
+		}
+
+		if (isReadOnly())
+			throw new SecurityException("attempt to add a Permission to a "
+					+ "readonly PermissionCollection");
+
+		hasElement = true;
+	}
+
+	/**
+	 * Determines if the specified set of permissions implies the permissions
+	 * expressed in the parameter <tt>permission</tt>.
+	 * 
+	 * @param p The Permission object to compare.
+	 * 
+	 * @return true if permission is a proper subset of a permission in the set;
+	 *         false otherwise.
+	 */
+
+	public boolean implies(Permission p) {
+		return hasElement && (p instanceof ConfigurationPermission);
+	}
+
+	/**
+	 * Returns an enumeration of an <tt>ConfigurationPermission</tt> object.
+	 * 
+	 * @return Enumeration of an <tt>ConfigurationPermission</tt> object.
+	 */
+
+	public Enumeration elements() {
+		return new Enumeration() {
+			private boolean	more	= hasElement;
+
+			public boolean hasMoreElements() {
+				return more;
+			}
+
+			public Object nextElement() {
+				if (more) {
+					more = false;
+
+					return new ConfigurationPermission("*",
+							ConfigurationPermission.CONFIGURE);
+				}
+				else {
+					throw new NoSuchElementException();
+				}
+			}
+		};
+	}
+
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
new file mode 100644
index 0000000..089e626
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
@@ -0,0 +1,131 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationPlugin.java,v 1.10 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.cm;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A service interface for processing configuration dictionary before the
+ * update.
+ * 
+ * <p>
+ * A bundle registers a <code>ConfigurationPlugin</code> object in order to
+ * process configuration updates before they reach the Managed Service or
+ * Managed Service Factory. The Configuration Admin service will detect
+ * registrations of Configuration Plugin services and must call these services
+ * every time before it calls the <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code>
+ * <code>updated</code> method. The
+ * Configuration Plugin service thus has the opportunity to view and modify the
+ * properties before they are passed to the ManagedS ervice or Managed Service
+ * Factory.
+ * 
+ * <p>
+ * Configuration Plugin (plugin) services have full read/write access to all
+ * configuration information. Therefore, bundles using this facility should be
+ * trusted. Access to this facility should be limited with
+ * <code>ServicePermission[ConfigurationPlugin,REGISTER]</code>.
+ * Implementations of a Configuration Plugin service should assure that they
+ * only act on appropriate configurations.
+ * 
+ * <p>
+ * The <code>Integer</code> <code>service.cmRanking</code> registration
+ * property may be specified. Not specifying this registration property, or
+ * setting it to something other than an <code>Integer</code>, is the same as
+ * setting it to the <code>Integer</code> zero. The
+ * <code>service.cmRanking</code> property determines the order in which
+ * plugins are invoked. Lower ranked plugins are called before higher ranked
+ * ones. In the event of more than one plugin having the same value of
+ * <code>service.cmRanking</code>, then the Configuration Admin service
+ * arbitrarily chooses the order in which they are called.
+ * 
+ * <p>
+ * By convention, plugins with <code>service.cmRanking&lt; 0</code> or
+ * <code>service.cmRanking &gt; 1000</code> should not make modifications to
+ * the properties.
+ * 
+ * <p>
+ * The Configuration Admin service has the right to hide properties from
+ * plugins, or to ignore some or all the changes that they make. This might be
+ * done for security reasons. Any such behavior is entirely implementation
+ * defined.
+ * 
+ * <p>
+ * A plugin may optionally specify a <code>cm.target</code> registration
+ * property whose value is the PID of the Managed Service or Managed Service
+ * Factory whose configuration updates the plugin is intended to intercept. The
+ * plugin will then only be called with configuration updates that are targetted
+ * at the Managed Service or Managed Service Factory with the specified PID.
+ * Omitting the <code>cm.target</code> registration property means that the
+ * plugin is called for all configuration updates.
+ * 
+ * @version $Revision: 1.10 $
+ */
+public interface ConfigurationPlugin {
+	/**
+	 * A service property to limit the Managed Service or Managed Service
+	 * Factory configuration dictionaries a Configuration Plugin service
+	 * receives.
+	 * 
+	 * This property contains a <code>String[]</code> of PIDs. A Configuration
+	 * Admin service must call a Configuration Plugin service only when this
+	 * property is not set, or the target service's PID is listed in this
+	 * property.
+	 */
+	public static final String	CM_TARGET	= "cm.target";
+	/**
+	 * A service property to specify the order in which plugins are invoked.
+	 * 
+	 * This property contains an <code>Integer</code> ranking of the plugin.
+	 * Not specifying this registration property, or setting it to something
+	 * other than an <code>Integer</code>, is the same as setting it to the
+	 * <code>Integer</code> zero. This property determines the order in which
+	 * plugins are invoked. Lower ranked plugins are called before higher ranked
+	 * ones.
+	 * 
+	 * @since 1.2
+	 */
+	public static final String	CM_RANKING	= "service.cmRanking";
+
+	/**
+	 * View and possibly modify the a set of configuration properties before
+	 * they are sent to the Managed Service or the Managed Service Factory. The
+	 * Configuration Plugin services are called in increasing order of their
+	 * <code>service.cmRanking</code> property. If this property is undefined
+	 * or is a non- <code>Integer</code> type, 0 is used.
+	 * 
+	 * <p>
+	 * This method should not modify the properties unless the
+	 * <code>service.cmRanking</code> of this plugin is in the range
+	 * <code>0 &lt;= service.cmRanking &lt;= 1000</code>.
+	 * <p>
+	 * If this method throws any <code>Exception</code>, the Configuration
+	 * Admin service must catch it and should log it.
+	 * 
+	 * @param reference reference to the Managed Service or Managed Service
+	 *        Factory
+	 * @param properties The configuration properties. This argument must not
+	 *        contain the "service.bundleLocation" property. The value of this
+	 *        property may be obtained from the
+	 *        <code>Configuration.getBundleLocation</code> method.
+	 */
+	public void modifyConfiguration(ServiceReference reference,
+			Dictionary properties);
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ManagedService.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ManagedService.java
new file mode 100644
index 0000000..b5ccce4
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ManagedService.java
@@ -0,0 +1,140 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ManagedService.java,v 1.11 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.cm;
+
+import java.util.Dictionary;
+
+/**
+ * A service that can receive configuration data from a Configuration Admin
+ * service.
+ * 
+ * <p>
+ * A Managed Service is a service that needs configuration data. Such an object
+ * should be registered with the Framework registry with the
+ * <code>service.pid</code> property set to some unique identitifier called a
+ * PID.
+ * 
+ * <p>
+ * If the Configuration Admin service has a <code>Configuration</code> object
+ * corresponding to this PID, it will callback the <code>updated()</code>
+ * method of the <code>ManagedService</code> object, passing the properties of
+ * that <code>Configuration</code> object.
+ * 
+ * <p>
+ * If it has no such <code>Configuration</code> object, then it calls back
+ * with a <code>null</code> properties argument. Registering a Managed Service
+ * will always result in a callback to the <code>updated()</code> method
+ * provided the Configuration Admin service is, or becomes active. This callback
+ * must always be done asynchronously.
+ * 
+ * <p>
+ * Else, every time that either of the <code>updated()</code> methods is
+ * called on that <code>Configuration</code> object, the
+ * <code>ManagedService.updated()</code> method with the new properties is
+ * called. If the <code>delete()</code> method is called on that
+ * <code>Configuration</code> object, <code>ManagedService.updated()</code>
+ * is called with a <code>null</code> for the properties parameter. All these
+ * callbacks must be done asynchronously.
+ * 
+ * <p>
+ * The following example shows the code of a serial port that will create a port
+ * depending on configuration information.
+ * 
+ * <pre>
+ *  
+ *   class SerialPort implements ManagedService {
+ *  
+ *     ServiceRegistration registration;
+ *     Hashtable configuration;
+ *     CommPortIdentifier id;
+ *  
+ *     synchronized void open(CommPortIdentifier id,
+ *     BundleContext context) {
+ *       this.id = id;
+ *       registration = context.registerService(
+ *         ManagedService.class.getName(),
+ *         this,
+ *         getDefaults()
+ *       );
+ *     }
+ *  
+ *     Hashtable getDefaults() {
+ *       Hashtable defaults = new Hashtable();
+ *       defaults.put( &quot;port&quot;, id.getName() );
+ *       defaults.put( &quot;product&quot;, &quot;unknown&quot; );
+ *       defaults.put( &quot;baud&quot;, &quot;9600&quot; );
+ *       defaults.put( Constants.SERVICE_PID,
+ *         &quot;com.acme.serialport.&quot; + id.getName() );
+ *       return defaults;
+ *     }
+ *  
+ *     public synchronized void updated(
+ *       Dictionary configuration  ) {
+ *       if ( configuration == 
+ * <code>
+ * null
+ * </code>
+ *   )
+ *         registration.setProperties( getDefaults() );
+ *       else {
+ *         setSpeed( configuration.get(&quot;baud&quot;) );
+ *         registration.setProperties( configuration );
+ *       }
+ *     }
+ *     ...
+ *   }
+ *   
+ * </pre>
+ * 
+ * <p>
+ * As a convention, it is recommended that when a Managed Service is updated, it
+ * should copy all the properties it does not recognize into the service
+ * registration properties. This will allow the Configuration Admin service to
+ * set properties on services which can then be used by other applications.
+ * 
+ * @version $Revision: 1.11 $
+ */
+public interface ManagedService {
+	/**
+	 * Update the configuration for a Managed Service.
+	 * 
+	 * <p>
+	 * When the implementation of <code>updated(Dictionary)</code> detects any
+	 * kind of error in the configuration properties, it should create a new
+	 * <code>ConfigurationException</code> which describes the problem. This
+	 * can allow a management system to provide useful information to a human
+	 * administrator.
+	 * 
+	 * <p>
+	 * If this method throws any other <code>Exception</code>, the
+	 * Configuration Admin service must catch it and should log it.
+	 * <p>
+	 * The Configuration Admin service must call this method asynchronously
+	 * which initiated the callback. This implies that implementors of Managed
+	 * Service can be assured that the callback will not take place during
+	 * registration when they execute the registration in a synchronized method.
+	 * 
+	 * @param properties A copy of the Configuration properties, or
+	 *        <code>null</code>. This argument must not contain the
+	 *        "service.bundleLocation" property. The value of this property may
+	 *        be obtained from the <code>Configuration.getBundleLocation</code>
+	 *        method.
+	 * @throws ConfigurationException when the update fails
+	 */
+	public void updated(Dictionary properties) throws ConfigurationException;
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
new file mode 100644
index 0000000..001ddd8
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
@@ -0,0 +1,162 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ManagedServiceFactory.java,v 1.10 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.cm;
+
+import java.util.Dictionary;
+
+/**
+ * Manage multiple service instances.
+ * 
+ * Bundles registering this interface are giving the Configuration Admin service
+ * the ability to create and configure a number of instances of a service that
+ * the implementing bundle can provide. For example, a bundle implementing a
+ * DHCP server could be instantiated multiple times for different interfaces
+ * using a factory.
+ * 
+ * <p>
+ * Each of these <i>service instances </i> is represented, in the persistent
+ * storage of the Configuration Admin service, by a factory
+ * <code>Configuration</code> object that has a PID. When such a
+ * <code>Configuration</code> is updated, the Configuration Admin service
+ * calls the <code>ManagedServiceFactory</code> updated method with the new
+ * properties. When <code>updated</code> is called with a new PID, the Managed
+ * Service Factory should create a new factory instance based on these
+ * configuration properties. When called with a PID that it has seen before, it
+ * should update that existing service instance with the new configuration
+ * information.
+ * 
+ * <p>
+ * In general it is expected that the implementation of this interface will
+ * maintain a data structure that maps PIDs to the factory instances that it has
+ * created. The semantics of a factory instance are defined by the Managed
+ * Service Factory. However, if the factory instance is registered as a service
+ * object with the service registry, its PID should match the PID of the
+ * corresponding <code>Configuration</code> object (but it should <b>not </b>
+ * be registered as a Managed Service!).
+ * 
+ * <p>
+ * An example that demonstrates the use of a factory. It will create serial
+ * ports under command of the Configuration Admin service.
+ * 
+ * <pre>
+ *  
+ *   class SerialPortFactory
+ *     implements ManagedServiceFactory {
+ *     ServiceRegistration registration;
+ *     Hashtable ports;
+ *     void start(BundleContext context) {
+ *       Hashtable properties = new Hashtable();
+ *       properties.put( Constants.SERVICE_PID,
+ *         &quot;com.acme.serialportfactory&quot; );
+ *       registration = context.registerService(
+ *         ManagedServiceFactory.class.getName(),
+ *         this,
+ *         properties
+ *       );
+ *     }
+ *     public void updated( String pid,
+ *       Dictionary properties  ) {
+ *       String portName = (String) properties.get(&quot;port&quot;);
+ *       SerialPortService port =
+ *         (SerialPort) ports.get( pid );
+ *       if ( port == null ) {
+ *         port = new SerialPortService();
+ *         ports.put( pid, port );
+ *         port.open();
+ *       }
+ *       if ( port.getPortName().equals(portName) )
+ *         return;
+ *       port.setPortName( portName );
+ *     }
+ *     public void deleted( String pid ) {
+ *       SerialPortService port =
+ *         (SerialPort) ports.get( pid );
+ *       port.close();
+ *       ports.remove( pid );
+ *     }
+ *     ...
+ *   }
+ *   
+ * </pre>
+ * 
+ * @version $Revision: 1.10 $
+ */
+public interface ManagedServiceFactory {
+	/**
+	 * Return a descriptive name of this factory.
+	 * 
+	 * @return the name for the factory, which might be localized
+	 */
+	public String getName();
+
+	/**
+	 * Create a new instance, or update the configuration of an existing
+	 * instance.
+	 * 
+	 * If the PID of the <code>Configuration</code> object is new for the
+	 * Managed Service Factory, then create a new factory instance, using the
+	 * configuration <code>properties</code> provided. Else, update the
+	 * service instance with the provided <code>properties</code>.
+	 * 
+	 * <p>
+	 * If the factory instance is registered with the Framework, then the
+	 * configuration <code>properties</code> should be copied to its registry
+	 * properties. This is not mandatory and security sensitive properties
+	 * should obviously not be copied.
+	 * 
+	 * <p>
+	 * If this method throws any <code>Exception</code>, the Configuration
+	 * Admin service must catch it and should log it.
+	 * 
+	 * <p>
+	 * When the implementation of updated detects any kind of error in the
+	 * configuration properties, it should create a new
+	 * {@link ConfigurationException}which describes the problem.
+	 * 
+	 * <p>
+	 * The Configuration Admin service must call this method asynchronously.
+	 * This implies that implementors of the <code>ManagedServiceFactory</code>
+	 * class can be assured that the callback will not take place during
+	 * registration when they execute the registration in a synchronized method.
+	 * 
+	 * @param pid The PID for this configuration.
+	 * @param properties A copy of the configuration properties. This argument
+	 *        must not contain the service.bundleLocation" property. The value
+	 *        of this property may be obtained from the
+	 *        <code>Configuration.getBundleLocation</code> method.
+	 * @throws ConfigurationException when the configuration properties are
+	 *         invalid.
+	 */
+	public void updated(String pid, Dictionary properties)
+			throws ConfigurationException;
+
+	/**
+	 * Remove a factory instance.
+	 * 
+	 * Remove the factory instance associated with the PID. If the instance was
+	 * registered with the service registry, it should be unregistered.
+	 * <p>
+	 * If this method throws any <code>Exception</code>, the Configuration
+	 * Admin service must catch it and should log it.
+	 * <p>
+	 * The Configuration Admin service must call this method asynchronously.
+	 * 
+	 * @param pid the PID of the service to be removed
+	 */
+	public void deleted(String pid);
+}
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/package.html b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/package.html
new file mode 100644
index 0000000..3f65348
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/package.html
@@ -0,0 +1,11 @@
+<!-- $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/package.html,v 1.2 2004/12/01 19:01:11 hargrave Exp $ -->
+<BODY>
+<P>The OSGi Configuration Admin service Package. Specification Version 1.2
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.cm; version=1.2
+</pre>
+</BODY>
+
diff --git a/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/packageinfo b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/packageinfo
@@ -0,0 +1 @@
+version 1.2